Books Algorithm Dealing with Square Digit Sums

-1

1

A little context:

  • Book has 411 Pages

  • Read a random number of pages on the first day which is unknown

  • Number of pages to read next day is the square of the sum of the digits of the page currently on

    I.e. on Page 36: read 81 pages next day

  • On day 6 The square answer directly adds to current page number to make 411

  • Finish Book

How many pages did she read on the first day and how many pages did she read on the 6 days?

This is what I have so far:

from itertools import accumulate, count

def read_book( start ):
    for i in range( 6 ): yield start; start += sum( int( digit ) for digit in str( start ) ) ** 2

def find_start( pages ):
    for start in count( 1 ):
        for read in read_book( start ): pass
        if read == pages: return start

previous_answer, start = 0, find_start( 411 )
for i, read in enumerate( read_book( start ), 1 ):
    print( "Pages read on day", i ,"was", read-previous_answer ,"\t(Now on page", str(read) + ")\n")
    previous_answer += read-previous_answer

Output:

Pages read on day 1 was 61 (Now on page 61)

Pages read on day 2 was 49 (Now on page 110)

Pages read on day 3 was 4 (Now on page 114)

Pages read on day 4 was 36 (Now on page 150)

Pages read on day 5 was 36 (Now on page 186)

Pages read on day 6 was 225 (Now on page 411)

Is there a more efficient way? Who can do it in the least no. chars

user36003

Posted 2015-01-10T20:41:23.230

Reputation:

4This has a fixed answer, so the shortest program will be just to print a single number. So, it doesn't make for a good challenge. Also, your code looks pretty un-compressed. Are you sure you're actually looking for a way to do it in few characters? – xnor – 2015-01-10T20:46:33.213

Yes I want all the functions to run (maybe as one mega-function if it has to be) but in the least amount of code possible: not just printing as this does not do any of the calculations/working out... – None – 2015-01-10T20:49:47.793

@Coolstar161 In that case you might want to make a few things variable (e.g. the number of days and the total number of pages). Otherwise it's really hard to draw the line on how much knowledge can be assumed for the problem. – Martin Ender – 2015-01-10T20:54:00.780

2I also think this would actually be an interesting challenge in general, if the input is variable. In that case you should remove the language-restriction to Python though. – Martin Ender – 2015-01-10T20:55:21.563

I'm sorry, I'm 16 and new to more complex coding so forgive me but I don't know what you mean... – None – 2015-01-10T20:57:30.433

def read_book( start, days=6 ): for i in range( days ): yield start; start += sum( int( digit ) for digit in str( start ) ) ** 2; this makes days variable??? – None – 2015-01-10T20:59:15.993

1@Coolstar161 Okay. Two things: 1. On this site we basically have two kinds of questions. a) Challenges, in which you people compete to solve a given problem while optimising towards a certain winning criterion (in this case, shortest code size). We like these to not be language-specific, so everyone can participate. b) Questions that ask for help shortening a specific piece of code. These will obviously be limited to the language of the reference code in the question. You should decide which of these you want. [cont.] – Martin Ender – 2015-01-10T21:01:19.203

1 start="2">

  • Currently there is no variable input to your problem. That means the output is also fixed as xnor mentioned, and in theory the problem can be reduced to a print. Now obviously, that's not what you want, because you don't want to assume you already know the solution. Then the question is, which parts of the challenge are variable? Only the number of days, the number of pages or both? Basically, the problem should be such that either 6, 411 or both are passed in through parameters and the code will work correctly for any other number. (Which raises the question if every input has a solution.)
  • < – Martin Ender – 2015-01-10T21:03:44.143

    Oh okay well I fall under Option 2: Shorten this code using Python Programming Language... (I think) – None – 2015-01-10T21:04:34.307

    1There is a problem with Part 2 of what you said: There is a very specific algorithm and this code will only work for certain book pages. The starting page and how many days are proportional so This makes it really hard!!! I don't know... I was advised by Stack Overflow to post on Code Review and Code Review advised to post it on Code-Golf: so where are you going to refer me to... – None – 2015-01-10T21:09:11.620

    6It's fairly common that people on one programming-related site in the StackExchange network will say that a question really belongs on a second one even though they don't participate much in the second one and might not really understand what its community considers on-topic. I don't see why your original question wasn't fine on StackOverflow, but since I don't participate there very much... I have one question about your goal: you ask whether there's a more efficient way and who can golf it the most. Are you asking two separate questions? Normally the shortest approach is the least efficient. – Peter Taylor – 2015-01-11T08:48:59.193

    Possibly. I want one solution which has been golfed (least number of lines). the second would be the most efficient solution – None – 2015-01-12T16:44:28.120

    Is this still up? Because I think I might be able to help. – ASCIIThenANSI – 2015-05-02T16:49:32.187

    Answers

    1

    gcc - 176 chars

    I don't grok Python (it is Python right?) so I don't understand how your example works. Is it actually treating the page number as a string?

    I'm not sure but (at least in C) string handling uses more characters than integers. So to sum the digits of an integer between 0 and 1000 I use:

    for(s=0,i=1;i<1001;i*=10)s+=(x%i*10)/i;
    

    Where x is the input and s is the sum.

    If you want the sum from some x for 7 days you could:

    for(c=2;c<7;x+=s*s,c++)
      for(s=0,i=1;i<1001;i*=10)s+=(x%i*10)/i;
    

    Where x is the input and the output.

    To find the sum for 7 days which matches the number of pages in the book (p):

    for(y=1;y<p&&x!=p;y++)
      for(x=y,c=2;c<7;x+=s*s,c++)
        for(s=0,i=1;i<1001;i*=10)s+=(x%i*10)/i;
    

    Where y-1 is the calculated starting page when the sum adds up to p.

    The whole program with which reads from the command line and prints to stdout:

    main(_,a)char**a;{
      int p=atoi(a[1]),s,i,y,x,c;
      for(y=1;y<p&&x!=p;y++)
        for(x=y,c=2;c<7;x+=s*s,c++)
          for(s=0,i=1;i<1001;i*=10)s+=(x%i*10)/i;
      if(x==p)printf("%d",y-1);else puts("n/a");
    }
    

    It surely is possible to golf it some more. If you see something that would help please comment.

    Jerry Jeremiah

    Posted 2015-01-10T20:41:23.230

    Reputation: 1 217