can I make this so the vm would not be not responsibe when running the tests

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

can I make this so the vm would not be not responsibe when running the tests

Pharo Smalltalk Users mailing list
Hello,

For a exercism challenge I need to calculate the total grains on a
chessboard.
So I did :

atSquare: anInteger
     self validateInput: anInteger.
     ^ anInteger = 1
         ifTrue: [ 1 ]
         ifFalse: [ 2 * (self atSquare: anInteger - 1) ]


but when I run the tests , the vm seems to be not responsive for some 4
- 5 seconds.

Is there a way I can use this code and take care that the vm stays
responsive.

Regards,

Roelof


Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

jtuchel
You can wrap the whole thing in a block and execute it in the background. Look for uses of fork: or forkAt:

Joachim

> Am 04.01.2020 um 18:46 schrieb Roelof Wobben via Pharo-users <[hidden email]>:
>
> <mime-attachment>


Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Richard Sargent
Administrator
In reply to this post by Pharo Smalltalk Users mailing list
On Sat, Jan 4, 2020 at 9:47 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
Hello,

For a exercism challenge I need to calculate the total grains on a
chessboard.
So I did :

atSquare: anInteger
     self validateInput: anInteger.
     ^ anInteger = 1
         ifTrue: [ 1 ]
         ifFalse: [ 2 * (self atSquare: anInteger - 1) ]


but when I run the tests , the vm seems to be not responsive for some 4
- 5 seconds.

Is there a way I can use this code and take care that the vm stays
responsive.

What do you want the VM to do in addition to calculating that sum while it is calculating that sum?


The best way to keep the VM responsive is to take a page from Gauss' notebook and pay attention to the numbers[1]. Let's consider the first four squares and extrapolate from there.

In binary, the squares hold the following grains: 2r1, 2r10, r2100, and 2r1000. When we add them up, we get 2r1111. If we use Gauss' tricks, we can notice that 2r1111 is equal to 2r10000 - 1. So, the sum of the grains on the first 4 squares is 2^5 - 1. You can easily generalize that pattern, of course. Then your program can calculate the answer quickly.


[1] The story goes that Gauss' teacher was frustrated with his student's abilities and set him a challenge to occupy him for some time: sum the numbers from 1 through 100. Gauss immediately answered 5,050, much to his teacher's chagrin.


Regards,

Roelof


Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Pharo Smalltalk Users mailing list
Oke,

So I can better not use recursion for this problem if I understand you well,  Richard.

Roelof



Op 4-1-2020 om 19:02 schreef Richard Sargent:
On Sat, Jan 4, 2020 at 9:47 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
Hello,

For a exercism challenge I need to calculate the total grains on a
chessboard.
So I did :

atSquare: anInteger
     self validateInput: anInteger.
     ^ anInteger = 1
         ifTrue: [ 1 ]
         ifFalse: [ 2 * (self atSquare: anInteger - 1) ]


but when I run the tests , the vm seems to be not responsive for some 4
- 5 seconds.

Is there a way I can use this code and take care that the vm stays
responsive.

What do you want the VM to do in addition to calculating that sum while it is calculating that sum?


The best way to keep the VM responsive is to take a page from Gauss' notebook and pay attention to the numbers[1]. Let's consider the first four squares and extrapolate from there.

In binary, the squares hold the following grains: 2r1, 2r10, r2100, and 2r1000. When we add them up, we get 2r1111. If we use Gauss' tricks, we can notice that 2r1111 is equal to 2r10000 - 1. So, the sum of the grains on the first 4 squares is 2^5 - 1. You can easily generalize that pattern, of course. Then your program can calculate the answer quickly.


[1] The story goes that Gauss' teacher was frustrated with his student's abilities and set him a challenge to occupy him for some time: sum the numbers from 1 through 100. Gauss immediately answered 5,050, much to his teacher's chagrin.


Regards,

Roelof



Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Richard Sargent
Administrator
On Sat, Jan 4, 2020 at 10:37 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
Oke,

So I can better not use recursion for this problem if I understand you well,  Richard.

That is oversimplifying. If the purpose of the *training* *exercise* is to learn how to use recursion, then using recursion is a necessary thing. If the purpose of the exercise is to solve a problem, understanding whether there are more efficient approaches to the solution is an essential skill.

This particular problem could have been solved using a recursive implementation, an iterative implementation, or a fundamental reframing of the problem to change it to an O(1) problem. Other problems are no so simply reframed.


One of the most important skills you will ever develop is to understand that a request for a feature may not be accurately describing the problem. A feature request is often a description of a problem from a single perspective. Learning to recognize whether it is one or the other will be crucial to your long-term success as a programmer.


Roelof



Op 4-1-2020 om 19:02 schreef Richard Sargent:
On Sat, Jan 4, 2020 at 9:47 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
Hello,

For a exercism challenge I need to calculate the total grains on a
chessboard.
So I did :

atSquare: anInteger
     self validateInput: anInteger.
     ^ anInteger = 1
         ifTrue: [ 1 ]
         ifFalse: [ 2 * (self atSquare: anInteger - 1) ]


but when I run the tests , the vm seems to be not responsive for some 4
- 5 seconds.

Is there a way I can use this code and take care that the vm stays
responsive.

What do you want the VM to do in addition to calculating that sum while it is calculating that sum?


The best way to keep the VM responsive is to take a page from Gauss' notebook and pay attention to the numbers[1]. Let's consider the first four squares and extrapolate from there.

In binary, the squares hold the following grains: 2r1, 2r10, r2100, and 2r1000. When we add them up, we get 2r1111. If we use Gauss' tricks, we can notice that 2r1111 is equal to 2r10000 - 1. So, the sum of the grains on the first 4 squares is 2^5 - 1. You can easily generalize that pattern, of course. Then your program can calculate the answer quickly.


[1] The story goes that Gauss' teacher was frustrated with his student's abilities and set him a challenge to occupy him for some time: sum the numbers from 1 through 100. Gauss immediately answered 5,050, much to his teacher's chagrin.


Regards,

Roelof



Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

tbrunz
Richard Sargent wrote
> One of the most important skills you will ever develop is to understand
> that a request for a feature may not be accurately describing the problem.
> A feature request is often a description of a problem from a single
> perspective. Learning to recognize whether it is one or the other will be
> crucial to your long-term success as a programmer.

Well put.  I would add a couple of others: Being able to interpret &
re-interpret feature requests, given that they are often poorly and
incompletely specified; this requires closing the loop with the customer to
ensure that your mutual understanding is spelled out clearly and agreed to.
Another is being able to skillfully negotiate feature and implementation
details with the customer to arrive at a requirements specification that not
only satisfies the customer's needs, but also specifies a system that you
can actually implement -- given the allotted schedule & budget and the
capabilities of your tools and team (which of course includes your own
know-how).

-t




--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Pharo Smalltalk Users mailing list
In reply to this post by Richard Sargent
Thanks for the lessson and its correct that English is not my mother language. Im from the Netherlands and were very bad at languages but good at math, science  and that sort of things at school.

Some of the names as squareAt:  were given by the exercism challenge.

The things you said about the computer challenge which was a AdventOfCode one I agree.  im still not happy with my answer at this moment.

For me at this point , its  something a puzzle to find a way to  make the code to solve things that I do not spend and think a lot about names.

That is why I asked here a few times on a mentor which can learn me how to solve things like the computer one the smalltalk way but it seems that every one is very busy with thier own projects and work, which I understand but for my feeling I do not come to a higher level to understand OOP and things like how to solve things the smalltalk way and also learn more how to name things better.  As you hint to use a person to explain it to me , I do not have. My wife works full-time and has at the evening no time to help me with this.

So im now in a doubt if I want to go on with smalltalk, which I find a pity because I love it.
But on solving this sort of puzzles and learning how to make my own websie in seaside , i  get the feeling my learning is coming to a still stand.

Also enoough rambling  on this side.

Roelof





Op 4-1-2020 om 22:11 schreef Richard Sargent:
On Sat, Jan 4, 2020 at 11:51 AM Roelof Wobben <[hidden email]> wrote:
Oke,

I have reread the challenge and a hint was to use recursion.
But also is said to think how you can make one for speed or readability.

And I find the one I made certain not good for readability.

Roelof,

I think you are making good progress on the mechanics of programming. However, I assume that English is not your first language. (I would be embarrassed by your answer if I were to ask how many you do know!)

One of the things you can improve - after you focus on proficiency in the programming language itself - is to look at how you name things and the concepts you articulate in your code. The following are a couple of examples, and aren't meant to shame you or anything like that.

In this latest exercise, your core method is named #squareAt:, but your model's terms are chessboard and grains of sand. A chessboard is planar, so addressing its squares really should use cartesian coordinates (x & y, or row and column, or rank and file). Of course, that would make this exercise more complicated, since the exercise really isn't about a chessboard. So, a better name might use the word grains in some way. e.g. #grainsAt: or #numberOfGrainsAt:. [1]

Your previous exercise was to simulate a computer. You had methods like #at: and #at:put: (if I recall correctly), but they were defined on the computer itself. In modelling, the computer comprises a processor, memory, storage, input, and output. In your code, you referred to the memory as RAM, but that's a technology. Random Access Memory. It is true that the memory you modelled is random access, but is that a relevant factor in your program? In my opinion it isn't. I think memory would have made a better name. And that suggests the methods you had on the computer for accessing memory were misnamed, at least, if not misplaced. In that exercise, there was no need for the computer to expose memory access. So, I think expressions like "memory at: anAddress" and "memory at: anAddress put: aValue" would be appropriate. In your exercise, memory was used to hold only integer values, so "anInteger" could have been the name of the argument without being incorrect.

Also, using a stream to iterate through the program was an interesting approach. An alternative, which would better mimic computer design, would entail the use of a program counter (an index) for addressing into memory. That would allow you to write expressions like "self operand: 1" (implemented as e,g, "memory at: pc+anOffset"). Of course, using a stream, you could implement #nextOperand and #storeResult: to encapsulate the stream.

In your class method, you had a good concept with naming a method with a verb (patch) since it was an action concept. I liked that you distinguished an unusual event from normal processing, even though both did the same thing, namely writing to memory. But, a name like #patchRamAt:value: is less sentence-like than e.g. #patchMemoryAt:with:. A keyword such as "value" carries little semantic information. In general, be careful about using vague words. value, process, and many others are worthless for communicating what it does or means. When you name a method argument, you want to convey as much about type and purpose as you reasonably can. "aValue" and "anObject" both tell the reader that it can be any kind of object at all. Usually, that isn't true. Simple methods like setters can simply use type to name the argument, since the keyword identifies the purpose of the argument. More complex methods often cannot get away with just naming by type. If there are multiple arguments of one type, calling them aString1 and aString2 is poor, since you are emphasizing their anonymity. firstNameString and lastNameString could be much better alternatives in a method which does anything complex. e.g. a "setter" method #firstName:lastName: that simply stores both names could easily call the arguments aString and anotherString. But, if you are going to do anything more with them in the method, you want them well distinguished from each other. This is both to help you avoid making errors and to help future readers more easily understand what they see.


There is a lot more I could say, but I don't want to overwhelm you. There are a number of idioms in Smalltalk which you will want to learn and incorporate into your own writing, as doing so will make your code more Smalltalky. :-) But, more importantly, it will make it more readable to other Smalltalk developers when you ask for help or advice. There are families of methods that communicate a lot but with great economy. #at:/#at:put:/#at:ifAbsent: (and in some cases #at:ifPresent:), #detect/#detect:ifNone:, #anySatisfy:/#allSatisfy:/#noneSatisfy, #select:/#collect:/#detect:/#reject:, etc.

One of the greatest idioms involves the #ifAbsent: concept. I don't think there are many (if any!) other languages that have this or make it so easy. Avoid using it to yield a nil, as that's an anti-pattern. Use it to control flow and show what is expected versus what is not expected yet not forbidden. Remember the exercise with the rules for the distance calculations? #ifNone: would let you return that fallback value if no rule applied, and yet have the main code clearly show that a rule is expected and what would be done with the rule that's found. That exercise was quite simple, but when you start dealing with complex things like insurance policies, etc., having code that clearly explains what's intended is crucial. (and, #ifAbsent: and #ifNone: are merely two examples. Create your own variants when you can and when it makes your code better/clearer. I have in many cases written methods with names structured like #doSomethingWith:or:, where the argument to #or: is a Block to simplify when the invoked method cannot do whatever it was expected to do. It means "I want to have you do something, but it's acceptable if conditions don't make that possible because I can deal with it.")




[1] Some great advice I was given about naming things: (1) Explain to a friend what a given artefact does. Or imagine doing so, but that's an advanced skill. Start with a real person who will respond with "Huh?"or the like when you say something that isn't clear. (2) Distill the explanation into a single concise sentence. If you cannot do that, chances are your artefact isn't well factored. It's a good indicator you need to rethink how you are envisioning the decomposition of the solution. (3) Throw away every word which doesn't change the meaning if it is present or not. At this point, you are moving away from a grammatical sentence to a name of a concept, so grammar no longer matters. (4) You should end up with a name which cannot be simplified further, yet is no bigger than necessary.


Enough rambling! I'm glad you're working in Pharo (Smalltalk). I wish you every success with it and with learning programming. Keep these thoughts in mind when you are deciding on names, but do focus on learning the mechanics.


Roelof


Op 4-1-2020 om 20:33 schreef Richard Sargent:
On Sat, Jan 4, 2020 at 10:37 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
Oke,

So I can better not use recursion for this problem if I understand you well,  Richard.

That is oversimplifying. If the purpose of the *training* *exercise* is to learn how to use recursion, then using recursion is a necessary thing. If the purpose of the exercise is to solve a problem, understanding whether there are more efficient approaches to the solution is an essential skill.

This particular problem could have been solved using a recursive implementation, an iterative implementation, or a fundamental reframing of the problem to change it to an O(1) problem. Other problems are no so simply reframed.


One of the most important skills you will ever develop is to understand that a request for a feature may not be accurately describing the problem. A feature request is often a description of a problem from a single perspective. Learning to recognize whether it is one or the other will be crucial to your long-term success as a programmer.


Roelof



Op 4-1-2020 om 19:02 schreef Richard Sargent:
On Sat, Jan 4, 2020 at 9:47 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
Hello,

For a exercism challenge I need to calculate the total grains on a
chessboard.
So I did :

atSquare: anInteger
     self validateInput: anInteger.
     ^ anInteger = 1
         ifTrue: [ 1 ]
         ifFalse: [ 2 * (self atSquare: anInteger - 1) ]


but when I run the tests , the vm seems to be not responsive for some 4
- 5 seconds.

Is there a way I can use this code and take care that the vm stays
responsive.

What do you want the VM to do in addition to calculating that sum while it is calculating that sum?


The best way to keep the VM responsive is to take a page from Gauss' notebook and pay attention to the numbers[1]. Let's consider the first four squares and extrapolate from there.

In binary, the squares hold the following grains: 2r1, 2r10, r2100, and 2r1000. When we add them up, we get 2r1111. If we use Gauss' tricks, we can notice that 2r1111 is equal to 2r10000 - 1. So, the sum of the grains on the first 4 squares is 2^5 - 1. You can easily generalize that pattern, of course. Then your program can calculate the answer quickly.


[1] The story goes that Gauss' teacher was frustrated with his student's abilities and set him a challenge to occupy him for some time: sum the numbers from 1 through 100. Gauss immediately answered 5,050, much to his teacher's chagrin.


Regards,

Roelof





Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Sean P. DeNigris
Administrator
Pharo Smalltalk Users mailing list wrote
> im still not happy with my answer at this moment.

Contrary to the delusion of "Learn [Programming Language] in 21 Days" or 7
minutes or 3 seconds or whatever the "code boot camps" are marketing these
days, mastering any language (and by extension programming in general)
probably will take a decade and countless hours.

I wouldn't get hung up on making this one exercise perfect. If it
accomplishes the task, move on to the next learning experiment. Everyone is
trying to help, but you don't have to assimilate this entire pile of great
advice in one day! Come back to this thread after a year of practice and
you'll likely be shocked how much more sense these comments make :)



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

tbrunz
Sean, I hope your comment doesn't discourage Roelof!  I might agree that
"mastery" of a given programming language could take a decade of working
with it, but it doesn't take anywhere near that long to "learn" a
programming language.

There are other factors, such as whether or not you already know at least
one language: you'll associate what you already know with the new ways of
doing the same sorts of things.  And you'll know to look for things that you
can reasonably expect a new language to provide.  But the first language you
learn will probably take the longest time, as expected.

I think learning Smalltalk/Pharo will take longer than you might expect if
the other languages you know are procedural or functional, rather than
object-oriented: You need to learn a new way of thinking when learning OOP
for the first time.  And that can be hard!  As humans, we're probably
"hard-wired" to think procedurally, which can be a bit of a handicap you
when starting OOP.

You don't need to, and shouldn't expect to be able to learn everything about
a programming language immediately, as you begin learning it.  Once you
learn the basics (enough to start writing programs that "do something"), you
need to begin writing programs --frequently-- and then begin the process of
incrementally adding to your understanding and knowledge of "the finer
details".  You learn as you go.  Reading up on the subject, including
reading others' code, helps a lot as well.  Today we have GitHub to help
there!

Don't give up, Roelof.  The struggles you go through now tell you that
you've progressed to the stage of "being aware of what you don't know",
which is good: It leads you to ask the right questions that will expand your
knowledge.  Finding the answers will sometimes be a challenge, but "mastery"
of a language pretty much always requires that you work through the kinds of
problems you've been having.  It's what gives you "insight", summed up as
"been there, done that".  Otherwise your knowledge of the language would
only be superficial (e.g., you would be able to read code examples, but you
wouldn't be able to code the examples on your own).

We've all been through these kinds of struggles you're having now.  It's
part of the process, not an indication of "you can't do it".  As Sean says,
after a year of working with Pharo, you'll be offering the same kinds of
advice to others that will follow you in getting started.  Just keep at it!



--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Pharo Smalltalk Users mailing list
Thanks.

I know that im at that stage and like I said I have the feeling that Im
at the stage for more then a half year.

I think I know a lot of pieces but need some help to see how the pieces
could help me to solve the more complex problems.

But maybe  I want to fast and I need to concentrate on simple websites
with seaside first and the problems of exercism and let the problems of
Advent of Code to a later point when I have more experience.  I know
that the problems of  Exercism are from easy to hard and maybe that is a
better way.

Roelof



Op 5-1-2020 om 03:34 schreef tbrunz:

> Sean, I hope your comment doesn't discourage Roelof!  I might agree that
> "mastery" of a given programming language could take a decade of working
> with it, but it doesn't take anywhere near that long to "learn" a
> programming language.
>
> There are other factors, such as whether or not you already know at least
> one language: you'll associate what you already know with the new ways of
> doing the same sorts of things.  And you'll know to look for things that you
> can reasonably expect a new language to provide.  But the first language you
> learn will probably take the longest time, as expected.
>
> I think learning Smalltalk/Pharo will take longer than you might expect if
> the other languages you know are procedural or functional, rather than
> object-oriented: You need to learn a new way of thinking when learning OOP
> for the first time.  And that can be hard!  As humans, we're probably
> "hard-wired" to think procedurally, which can be a bit of a handicap you
> when starting OOP.
>
> You don't need to, and shouldn't expect to be able to learn everything about
> a programming language immediately, as you begin learning it.  Once you
> learn the basics (enough to start writing programs that "do something"), you
> need to begin writing programs --frequently-- and then begin the process of
> incrementally adding to your understanding and knowledge of "the finer
> details".  You learn as you go.  Reading up on the subject, including
> reading others' code, helps a lot as well.  Today we have GitHub to help
> there!
>
> Don't give up, Roelof.  The struggles you go through now tell you that
> you've progressed to the stage of "being aware of what you don't know",
> which is good: It leads you to ask the right questions that will expand your
> knowledge.  Finding the answers will sometimes be a challenge, but "mastery"
> of a language pretty much always requires that you work through the kinds of
> problems you've been having.  It's what gives you "insight", summed up as
> "been there, done that".  Otherwise your knowledge of the language would
> only be superficial (e.g., you would be able to read code examples, but you
> wouldn't be able to code the examples on your own).
>
> We've all been through these kinds of struggles you're having now.  It's
> part of the process, not an indication of "you can't do it".  As Sean says,
> after a year of working with Pharo, you'll be offering the same kinds of
> advice to others that will follow you in getting started.  Just keep at it!
>
>
>
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html
>
>


Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Richard O'Keefe
In reply to this post by Pharo Smalltalk Users mailing list
Time microsecondsToRun: [
    |n|
    n := (2 raisedToInteger: 8 * 8) - 1.
    Transcript
        nextPutAll: 'The number of grains on an 8x8 chessboard is ';
print: n; cr; endEntry].
<PRINT-IT>
On my laptop, this reports 194 microseconds.

Why would you use recursion, anyway?

Time microsecondsToRun: [
    |n|
    n := (1 to: 8 * 8) inject: 0 into: [:acc :each | acc+acc+1].
    Transcript
        nextPutAll: 'The number of grains on an 8x8 chessboard is ';
print: n; cr; endEntry].
<PRINT-IT>
On the same laptop, this reports 118 microseconds.

One of the lessons of 'functional' languages, promptly adopted by Smalltalk, is
to encapsulate control structures into reusable methods, such as #inject:into:,
more commonly known as `foldl` in functional languages.  It's then none of
my business whether such a method works by recursion, iteration, or gangs
of otherwise seasonally unemployed Christmas elves.

In my own Smalltalk library,
  (GeometricSeries new: 64 from: 1 byFactor: 2) sum
only takes 15 microseconds.

I do note that you are calling validateInput repeatedly.  Why?


On Sun, 5 Jan 2020 at 07:41, Roelof Wobben via Pharo-users
<[hidden email]> wrote:

>
> Oke,
>
> So I can better not use recursion for this problem if I understand you well,  Richard.
>
> Roelof
>
>
>
> Op 4-1-2020 om 19:02 schreef Richard Sargent:
>
> On Sat, Jan 4, 2020 at 9:47 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
>>
>> Hello,
>>
>> For a exercism challenge I need to calculate the total grains on a
>> chessboard.
>> So I did :
>>
>> atSquare: anInteger
>>      self validateInput: anInteger.
>>      ^ anInteger = 1
>>          ifTrue: [ 1 ]
>>          ifFalse: [ 2 * (self atSquare: anInteger - 1) ]
>>
>>
>> but when I run the tests , the vm seems to be not responsive for some 4
>> - 5 seconds.
>>
>> Is there a way I can use this code and take care that the vm stays
>> responsive.
>
>
> What do you want the VM to do in addition to calculating that sum while it is calculating that sum?
>
>
> The best way to keep the VM responsive is to take a page from Gauss' notebook and pay attention to the numbers[1]. Let's consider the first four squares and extrapolate from there.
>
> In binary, the squares hold the following grains: 2r1, 2r10, r2100, and 2r1000. When we add them up, we get 2r1111. If we use Gauss' tricks, we can notice that 2r1111 is equal to 2r10000 - 1. So, the sum of the grains on the first 4 squares is 2^5 - 1. You can easily generalize that pattern, of course. Then your program can calculate the answer quickly.
>
>
> [1] The story goes that Gauss' teacher was frustrated with his student's abilities and set him a challenge to occupy him for some time: sum the numbers from 1 through 100. Gauss immediately answered 5,050, much to his teacher's chagrin.
>
>>
>> Regards,
>>
>> Roelof
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Pharo Smalltalk Users mailing list
Hello Ricard.

You mean when I calcualate the total of a board.
That is because on when I had to calculate the number of a particular
field there were tests where the number was lower then zero or higher
then 64 which makes no sense.

But im open for a solution where on a particular field I could check for
that and for the total I do not need that part.

Roelof



Op 5-1-2020 om 13:58 schreef Richard O'Keefe:

> Time microsecondsToRun: [
>      |n|
>      n := (2 raisedToInteger: 8 * 8) - 1.
>      Transcript
>          nextPutAll: 'The number of grains on an 8x8 chessboard is ';
> print: n; cr; endEntry].
> <PRINT-IT>
> On my laptop, this reports 194 microseconds.
>
> Why would you use recursion, anyway?
>
> Time microsecondsToRun: [
>      |n|
>      n := (1 to: 8 * 8) inject: 0 into: [:acc :each | acc+acc+1].
>      Transcript
>          nextPutAll: 'The number of grains on an 8x8 chessboard is ';
> print: n; cr; endEntry].
> <PRINT-IT>
> On the same laptop, this reports 118 microseconds.
>
> One of the lessons of 'functional' languages, promptly adopted by Smalltalk, is
> to encapsulate control structures into reusable methods, such as #inject:into:,
> more commonly known as `foldl` in functional languages.  It's then none of
> my business whether such a method works by recursion, iteration, or gangs
> of otherwise seasonally unemployed Christmas elves.
>
> In my own Smalltalk library,
>    (GeometricSeries new: 64 from: 1 byFactor: 2) sum
> only takes 15 microseconds.
>
> I do note that you are calling validateInput repeatedly.  Why?
>
>
> On Sun, 5 Jan 2020 at 07:41, Roelof Wobben via Pharo-users
> <[hidden email]> wrote:
>> Oke,
>>
>> So I can better not use recursion for this problem if I understand you well,  Richard.
>>
>> Roelof
>>
>>
>>
>> Op 4-1-2020 om 19:02 schreef Richard Sargent:
>>
>> On Sat, Jan 4, 2020 at 9:47 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
>>> Hello,
>>>
>>> For a exercism challenge I need to calculate the total grains on a
>>> chessboard.
>>> So I did :
>>>
>>> atSquare: anInteger
>>>       self validateInput: anInteger.
>>>       ^ anInteger = 1
>>>           ifTrue: [ 1 ]
>>>           ifFalse: [ 2 * (self atSquare: anInteger - 1) ]
>>>
>>>
>>> but when I run the tests , the vm seems to be not responsive for some 4
>>> - 5 seconds.
>>>
>>> Is there a way I can use this code and take care that the vm stays
>>> responsive.
>>
>> What do you want the VM to do in addition to calculating that sum while it is calculating that sum?
>>
>>
>> The best way to keep the VM responsive is to take a page from Gauss' notebook and pay attention to the numbers[1]. Let's consider the first four squares and extrapolate from there.
>>
>> In binary, the squares hold the following grains: 2r1, 2r10, r2100, and 2r1000. When we add them up, we get 2r1111. If we use Gauss' tricks, we can notice that 2r1111 is equal to 2r10000 - 1. So, the sum of the grains on the first 4 squares is 2^5 - 1. You can easily generalize that pattern, of course. Then your program can calculate the answer quickly.
>>
>>
>> [1] The story goes that Gauss' teacher was frustrated with his student's abilities and set him a challenge to occupy him for some time: sum the numbers from 1 through 100. Gauss immediately answered 5,050, much to his teacher's chagrin.
>>
>>> Regards,
>>>
>>> Roelof
>>>
>>>


Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Richard O'Keefe
In reply to this post by Richard O'Keefe
I did not ask why you were validating input.
I asked about why you *repeatedly* validated input.

Think of it this way:
   publicMethod: arg1 also: arg2
      ... check arg1 ...
      ... check arg2 ...
     ^self privateMethod: arg1 also: arg2

    privateMethod: arg1 also: arg2
      ... trust that arg1 and arg2 are valide ...
      ... recursive calls use #privateMethod:andAlso: ...
      ... not #publicMethod:andAlso: and must ensure ...
      ... that arguments are valid by construction ...

In my solution to the "Grains" exercism, I have
  atSquare: n   -- checks its argument
  total ^(1 bitShift: 64) - 1
You are required to implement these two methods, true.
You are NOT required to implement #total by calling #atSquare:.
Not even once.  Nor is #atSquare: required to be recursive.

On Mon, 6 Jan 2020 at 02:05, Roelof Wobben <[hidden email]> wrote:

>
> Hello Ricard.
>
> You mean when I calcualate the total of a board.
> That is because on when I had to calculate the number of a particular
> field there were tests where the number was lower then zero or higher
> then 64 which makes no sense.
>
> But im open for a solution where on a particular field I could check for
> that and for the total I do not need that part.
>
> Roelof
>
>
>
> Op 5-1-2020 om 13:58 schreef Richard O'Keefe:
> > Time microsecondsToRun: [
> >      |n|
> >      n := (2 raisedToInteger: 8 * 8) - 1.
> >      Transcript
> >          nextPutAll: 'The number of grains on an 8x8 chessboard is ';
> > print: n; cr; endEntry].
> > <PRINT-IT>
> > On my laptop, this reports 194 microseconds.
> >
> > Why would you use recursion, anyway?
> >
> > Time microsecondsToRun: [
> >      |n|
> >      n := (1 to: 8 * 8) inject: 0 into: [:acc :each | acc+acc+1].
> >      Transcript
> >          nextPutAll: 'The number of grains on an 8x8 chessboard is ';
> > print: n; cr; endEntry].
> > <PRINT-IT>
> > On the same laptop, this reports 118 microseconds.
> >
> > One of the lessons of 'functional' languages, promptly adopted by Smalltalk, is
> > to encapsulate control structures into reusable methods, such as #inject:into:,
> > more commonly known as `foldl` in functional languages.  It's then none of
> > my business whether such a method works by recursion, iteration, or gangs
> > of otherwise seasonally unemployed Christmas elves.
> >
> > In my own Smalltalk library,
> >    (GeometricSeries new: 64 from: 1 byFactor: 2) sum
> > only takes 15 microseconds.
> >
> > I do note that you are calling validateInput repeatedly.  Why?
> >
> >
> > On Sun, 5 Jan 2020 at 07:41, Roelof Wobben via Pharo-users
> > <[hidden email]> wrote:
> >> Oke,
> >>
> >> So I can better not use recursion for this problem if I understand you well,  Richard.
> >>
> >> Roelof
> >>
> >>
> >>
> >> Op 4-1-2020 om 19:02 schreef Richard Sargent:
> >>
> >> On Sat, Jan 4, 2020 at 9:47 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
> >>> Hello,
> >>>
> >>> For a exercism challenge I need to calculate the total grains on a
> >>> chessboard.
> >>> So I did :
> >>>
> >>> atSquare: anInteger
> >>>       self validateInput: anInteger.
> >>>       ^ anInteger = 1
> >>>           ifTrue: [ 1 ]
> >>>           ifFalse: [ 2 * (self atSquare: anInteger - 1) ]
> >>>
> >>>
> >>> but when I run the tests , the vm seems to be not responsive for some 4
> >>> - 5 seconds.
> >>>
> >>> Is there a way I can use this code and take care that the vm stays
> >>> responsive.
> >>
> >> What do you want the VM to do in addition to calculating that sum while it is calculating that sum?
> >>
> >>
> >> The best way to keep the VM responsive is to take a page from Gauss' notebook and pay attention to the numbers[1]. Let's consider the first four squares and extrapolate from there.
> >>
> >> In binary, the squares hold the following grains: 2r1, 2r10, r2100, and 2r1000. When we add them up, we get 2r1111. If we use Gauss' tricks, we can notice that 2r1111 is equal to 2r10000 - 1. So, the sum of the grains on the first 4 squares is 2^5 - 1. You can easily generalize that pattern, of course. Then your program can calculate the answer quickly.
> >>
> >>
> >> [1] The story goes that Gauss' teacher was frustrated with his student's abilities and set him a challenge to occupy him for some time: sum the numbers from 1 through 100. Gauss immediately answered 5,050, much to his teacher's chagrin.
> >>
> >>> Regards,
> >>>
> >>> Roelof
> >>>
> >>>
>

Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Pharo Smalltalk Users mailing list
There you are right but the hint we get was thinking about recursion

but your lessons showed me other ways to do it which I think are more
the way smalltalk works,
Thanks for that.

Roelof




Op 5-1-2020 om 14:24 schreef Richard O'Keefe:

> I did not ask why you were validating input.
> I asked about why you *repeatedly* validated input.
>
> Think of it this way:
>     publicMethod: arg1 also: arg2
>        ... check arg1 ...
>        ... check arg2 ...
>       ^self privateMethod: arg1 also: arg2
>
>      privateMethod: arg1 also: arg2
>        ... trust that arg1 and arg2 are valide ...
>        ... recursive calls use #privateMethod:andAlso: ...
>        ... not #publicMethod:andAlso: and must ensure ...
>        ... that arguments are valid by construction ...
>
> In my solution to the "Grains" exercism, I have
>    atSquare: n   -- checks its argument
>    total ^(1 bitShift: 64) - 1
> You are required to implement these two methods, true.
> You are NOT required to implement #total by calling #atSquare:.
> Not even once.  Nor is #atSquare: required to be recursive.
>
> On Mon, 6 Jan 2020 at 02:05, Roelof Wobben <[hidden email]> wrote:
>> Hello Ricard.
>>
>> You mean when I calcualate the total of a board.
>> That is because on when I had to calculate the number of a particular
>> field there were tests where the number was lower then zero or higher
>> then 64 which makes no sense.
>>
>> But im open for a solution where on a particular field I could check for
>> that and for the total I do not need that part.
>>
>> Roelof
>>
>>
>>
>> Op 5-1-2020 om 13:58 schreef Richard O'Keefe:
>>> Time microsecondsToRun: [
>>>       |n|
>>>       n := (2 raisedToInteger: 8 * 8) - 1.
>>>       Transcript
>>>           nextPutAll: 'The number of grains on an 8x8 chessboard is ';
>>> print: n; cr; endEntry].
>>> <PRINT-IT>
>>> On my laptop, this reports 194 microseconds.
>>>
>>> Why would you use recursion, anyway?
>>>
>>> Time microsecondsToRun: [
>>>       |n|
>>>       n := (1 to: 8 * 8) inject: 0 into: [:acc :each | acc+acc+1].
>>>       Transcript
>>>           nextPutAll: 'The number of grains on an 8x8 chessboard is ';
>>> print: n; cr; endEntry].
>>> <PRINT-IT>
>>> On the same laptop, this reports 118 microseconds.
>>>
>>> One of the lessons of 'functional' languages, promptly adopted by Smalltalk, is
>>> to encapsulate control structures into reusable methods, such as #inject:into:,
>>> more commonly known as `foldl` in functional languages.  It's then none of
>>> my business whether such a method works by recursion, iteration, or gangs
>>> of otherwise seasonally unemployed Christmas elves.
>>>
>>> In my own Smalltalk library,
>>>     (GeometricSeries new: 64 from: 1 byFactor: 2) sum
>>> only takes 15 microseconds.
>>>
>>> I do note that you are calling validateInput repeatedly.  Why?
>>>
>>>
>>> On Sun, 5 Jan 2020 at 07:41, Roelof Wobben via Pharo-users
>>> <[hidden email]> wrote:
>>>> Oke,
>>>>
>>>> So I can better not use recursion for this problem if I understand you well,  Richard.
>>>>
>>>> Roelof
>>>>
>>>>
>>>>
>>>> Op 4-1-2020 om 19:02 schreef Richard Sargent:
>>>>
>>>> On Sat, Jan 4, 2020 at 9:47 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
>>>>> Hello,
>>>>>
>>>>> For a exercism challenge I need to calculate the total grains on a
>>>>> chessboard.
>>>>> So I did :
>>>>>
>>>>> atSquare: anInteger
>>>>>        self validateInput: anInteger.
>>>>>        ^ anInteger = 1
>>>>>            ifTrue: [ 1 ]
>>>>>            ifFalse: [ 2 * (self atSquare: anInteger - 1) ]
>>>>>
>>>>>
>>>>> but when I run the tests , the vm seems to be not responsive for some 4
>>>>> - 5 seconds.
>>>>>
>>>>> Is there a way I can use this code and take care that the vm stays
>>>>> responsive.
>>>> What do you want the VM to do in addition to calculating that sum while it is calculating that sum?
>>>>
>>>>
>>>> The best way to keep the VM responsive is to take a page from Gauss' notebook and pay attention to the numbers[1]. Let's consider the first four squares and extrapolate from there.
>>>>
>>>> In binary, the squares hold the following grains: 2r1, 2r10, r2100, and 2r1000. When we add them up, we get 2r1111. If we use Gauss' tricks, we can notice that 2r1111 is equal to 2r10000 - 1. So, the sum of the grains on the first 4 squares is 2^5 - 1. You can easily generalize that pattern, of course. Then your program can calculate the answer quickly.
>>>>
>>>>
>>>> [1] The story goes that Gauss' teacher was frustrated with his student's abilities and set him a challenge to occupy him for some time: sum the numbers from 1 through 100. Gauss immediately answered 5,050, much to his teacher's chagrin.
>>>>
>>>>> Regards,
>>>>>
>>>>> Roelof
>>>>>
>>>>>


Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Ben Coman
In reply to this post by Richard O'Keefe
Hi Richard,

Just fyi, the aim of Exercism is not to teach programming.  Its aim is for experienced programmers to fast-start in new languages.
It just happens to that new programmers also use Exercism and there is some catering in the exercise text for this.

The grains exercise provides a nice vehicle for programmers to familiarize themselves with recursion in Pharo, 
and the hint for the exercise says "These kinds of problems (where an answer is dependent on a previous) one are often called recursion"  
which is why Roelof is approaching the problem this way. 

That said, any solution will do.  Your advice on alternative considerations is insightful and always good to read.

cheers -ben

On Mon, 6 Jan 2020 at 00:25, Richard O'Keefe <[hidden email]> wrote:
I did not ask why you were validating input.
I asked about why you *repeatedly* validated input.

Think of it this way:
   publicMethod: arg1 also: arg2
      ... check arg1 ...
      ... check arg2 ...
     ^self privateMethod: arg1 also: arg2

    privateMethod: arg1 also: arg2
      ... trust that arg1 and arg2 are valide ...
      ... recursive calls use #privateMethod:andAlso: ...
      ... not #publicMethod:andAlso: and must ensure ...
      ... that arguments are valid by construction ...

In my solution to the "Grains" exercism, I have
  atSquare: n   -- checks its argument
  total ^(1 bitShift: 64) - 1
You are required to implement these two methods, true.
You are NOT required to implement #total by calling #atSquare:.
Not even once.  Nor is #atSquare: required to be recursive.

On Mon, 6 Jan 2020 at 02:05, Roelof Wobben <[hidden email]> wrote:
>
> Hello Ricard.
>
> You mean when I calcualate the total of a board.
> That is because on when I had to calculate the number of a particular
> field there were tests where the number was lower then zero or higher
> then 64 which makes no sense.
>
> But im open for a solution where on a particular field I could check for
> that and for the total I do not need that part.
>
> Roelof
>
>
>
> Op 5-1-2020 om 13:58 schreef Richard O'Keefe:
> > Time microsecondsToRun: [
> >      |n|
> >      n := (2 raisedToInteger: 8 * 8) - 1.
> >      Transcript
> >          nextPutAll: 'The number of grains on an 8x8 chessboard is ';
> > print: n; cr; endEntry].
> > <PRINT-IT>
> > On my laptop, this reports 194 microseconds.
> >
> > Why would you use recursion, anyway?
> >
> > Time microsecondsToRun: [
> >      |n|
> >      n := (1 to: 8 * 8) inject: 0 into: [:acc :each | acc+acc+1].
> >      Transcript
> >          nextPutAll: 'The number of grains on an 8x8 chessboard is ';
> > print: n; cr; endEntry].
> > <PRINT-IT>
> > On the same laptop, this reports 118 microseconds.
> >
> > One of the lessons of 'functional' languages, promptly adopted by Smalltalk, is
> > to encapsulate control structures into reusable methods, such as #inject:into:,
> > more commonly known as `foldl` in functional languages.  It's then none of
> > my business whether such a method works by recursion, iteration, or gangs
> > of otherwise seasonally unemployed Christmas elves.
> >
> > In my own Smalltalk library,
> >    (GeometricSeries new: 64 from: 1 byFactor: 2) sum
> > only takes 15 microseconds.
> >
> > I do note that you are calling validateInput repeatedly.  Why?
> >
> >
> > On Sun, 5 Jan 2020 at 07:41, Roelof Wobben via Pharo-users
> > <[hidden email]> wrote:
> >> Oke,
> >>
> >> So I can better not use recursion for this problem if I understand you well,  Richard.
> >>
> >> Roelof
> >>
> >>
> >>
> >> Op 4-1-2020 om 19:02 schreef Richard Sargent:
> >>
> >> On Sat, Jan 4, 2020 at 9:47 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
> >>> Hello,
> >>>
> >>> For a exercism challenge I need to calculate the total grains on a
> >>> chessboard.
> >>> So I did :
> >>>
> >>> atSquare: anInteger
> >>>       self validateInput: anInteger.
> >>>       ^ anInteger = 1
> >>>           ifTrue: [ 1 ]
> >>>           ifFalse: [ 2 * (self atSquare: anInteger - 1) ]
> >>>
> >>>
> >>> but when I run the tests , the vm seems to be not responsive for some 4
> >>> - 5 seconds.
> >>>
> >>> Is there a way I can use this code and take care that the vm stays
> >>> responsive.
> >>
> >> What do you want the VM to do in addition to calculating that sum while it is calculating that sum?
> >>
> >>
> >> The best way to keep the VM responsive is to take a page from Gauss' notebook and pay attention to the numbers[1]. Let's consider the first four squares and extrapolate from there.
> >>
> >> In binary, the squares hold the following grains: 2r1, 2r10, r2100, and 2r1000. When we add them up, we get 2r1111. If we use Gauss' tricks, we can notice that 2r1111 is equal to 2r10000 - 1. So, the sum of the grains on the first 4 squares is 2^5 - 1. You can easily generalize that pattern, of course. Then your program can calculate the answer quickly.
> >>
> >>
> >> [1] The story goes that Gauss' teacher was frustrated with his student's abilities and set him a challenge to occupy him for some time: sum the numbers from 1 through 100. Gauss immediately answered 5,050, much to his teacher's chagrin.
> >>
> >>> Regards,
> >>>
> >>> Roelof
> >>>
> >>>
>

Reply | Threaded
Open this post in threaded view
|

Re: can I make this so the vm would not be not responsibe when running the tests

Richard O'Keefe
Well, no. This is not a particularly "nice vehicle for programmers to
familiarise themselves with recursion".
To start with, a quick web search turns up
https://en.wikipedia.org/wiki/Wheat_and_chessboard_problem.
Problems where the result depend on previous results often fall into
the "dynamic programming" category,
with

Object subclass: #ChessBoard
  instanceVariableNames: 'board sum'
  class methods for: 'instance creation'
    new: n
      ^self new initialize: n
  methods for: 'initializing;
    initialize: n
      board := Array new: n squared.
      board at: 1 put: 1.
      2 to: board size do: [:i |
        board at: i put: (board at: i - 1) * 2].
      sum := 0.
      board do: [:each |
        sum := sum + each].
      ^self
  methods for: 'accessing'
   squareAt: i
      ^board at: i
    total
      ^sum

being the most obvious elementary implementation.  The very
description of the problem
suggests an iterative approach.

To find a nice problem for recursion, you have to find one where
tabulation is *not* a
good strategy.

On Mon, 6 Jan 2020 at 08:06, Ben Coman <[hidden email]> wrote:

>
> Hi Richard,
>
> Just fyi, the aim of Exercism is not to teach programming.  Its aim is for experienced programmers to fast-start in new languages.
> It just happens to that new programmers also use Exercism and there is some catering in the exercise text for this.
>
> The grains exercise provides a nice vehicle for programmers to familiarize themselves with recursion in Pharo,
> and the hint for the exercise says "These kinds of problems (where an answer is dependent on a previous) one are often called recursion"
> which is why Roelof is approaching the problem this way.
>
> That said, any solution will do.  Your advice on alternative considerations is insightful and always good to read.
>
> cheers -ben
>
> On Mon, 6 Jan 2020 at 00:25, Richard O'Keefe <[hidden email]> wrote:
>>
>> I did not ask why you were validating input.
>> I asked about why you *repeatedly* validated input.
>>
>> Think of it this way:
>>    publicMethod: arg1 also: arg2
>>       ... check arg1 ...
>>       ... check arg2 ...
>>      ^self privateMethod: arg1 also: arg2
>>
>>     privateMethod: arg1 also: arg2
>>       ... trust that arg1 and arg2 are valide ...
>>       ... recursive calls use #privateMethod:andAlso: ...
>>       ... not #publicMethod:andAlso: and must ensure ...
>>       ... that arguments are valid by construction ...
>>
>> In my solution to the "Grains" exercism, I have
>>   atSquare: n   -- checks its argument
>>   total ^(1 bitShift: 64) - 1
>> You are required to implement these two methods, true.
>> You are NOT required to implement #total by calling #atSquare:.
>> Not even once.  Nor is #atSquare: required to be recursive.
>>
>> On Mon, 6 Jan 2020 at 02:05, Roelof Wobben <[hidden email]> wrote:
>> >
>> > Hello Ricard.
>> >
>> > You mean when I calcualate the total of a board.
>> > That is because on when I had to calculate the number of a particular
>> > field there were tests where the number was lower then zero or higher
>> > then 64 which makes no sense.
>> >
>> > But im open for a solution where on a particular field I could check for
>> > that and for the total I do not need that part.
>> >
>> > Roelof
>> >
>> >
>> >
>> > Op 5-1-2020 om 13:58 schreef Richard O'Keefe:
>> > > Time microsecondsToRun: [
>> > >      |n|
>> > >      n := (2 raisedToInteger: 8 * 8) - 1.
>> > >      Transcript
>> > >          nextPutAll: 'The number of grains on an 8x8 chessboard is ';
>> > > print: n; cr; endEntry].
>> > > <PRINT-IT>
>> > > On my laptop, this reports 194 microseconds.
>> > >
>> > > Why would you use recursion, anyway?
>> > >
>> > > Time microsecondsToRun: [
>> > >      |n|
>> > >      n := (1 to: 8 * 8) inject: 0 into: [:acc :each | acc+acc+1].
>> > >      Transcript
>> > >          nextPutAll: 'The number of grains on an 8x8 chessboard is ';
>> > > print: n; cr; endEntry].
>> > > <PRINT-IT>
>> > > On the same laptop, this reports 118 microseconds.
>> > >
>> > > One of the lessons of 'functional' languages, promptly adopted by Smalltalk, is
>> > > to encapsulate control structures into reusable methods, such as #inject:into:,
>> > > more commonly known as `foldl` in functional languages.  It's then none of
>> > > my business whether such a method works by recursion, iteration, or gangs
>> > > of otherwise seasonally unemployed Christmas elves.
>> > >
>> > > In my own Smalltalk library,
>> > >    (GeometricSeries new: 64 from: 1 byFactor: 2) sum
>> > > only takes 15 microseconds.
>> > >
>> > > I do note that you are calling validateInput repeatedly.  Why?
>> > >
>> > >
>> > > On Sun, 5 Jan 2020 at 07:41, Roelof Wobben via Pharo-users
>> > > <[hidden email]> wrote:
>> > >> Oke,
>> > >>
>> > >> So I can better not use recursion for this problem if I understand you well,  Richard.
>> > >>
>> > >> Roelof
>> > >>
>> > >>
>> > >>
>> > >> Op 4-1-2020 om 19:02 schreef Richard Sargent:
>> > >>
>> > >> On Sat, Jan 4, 2020 at 9:47 AM Roelof Wobben via Pharo-users <[hidden email]> wrote:
>> > >>> Hello,
>> > >>>
>> > >>> For a exercism challenge I need to calculate the total grains on a
>> > >>> chessboard.
>> > >>> So I did :
>> > >>>
>> > >>> atSquare: anInteger
>> > >>>       self validateInput: anInteger.
>> > >>>       ^ anInteger = 1
>> > >>>           ifTrue: [ 1 ]
>> > >>>           ifFalse: [ 2 * (self atSquare: anInteger - 1) ]
>> > >>>
>> > >>>
>> > >>> but when I run the tests , the vm seems to be not responsive for some 4
>> > >>> - 5 seconds.
>> > >>>
>> > >>> Is there a way I can use this code and take care that the vm stays
>> > >>> responsive.
>> > >>
>> > >> What do you want the VM to do in addition to calculating that sum while it is calculating that sum?
>> > >>
>> > >>
>> > >> The best way to keep the VM responsive is to take a page from Gauss' notebook and pay attention to the numbers[1]. Let's consider the first four squares and extrapolate from there.
>> > >>
>> > >> In binary, the squares hold the following grains: 2r1, 2r10, r2100, and 2r1000. When we add them up, we get 2r1111. If we use Gauss' tricks, we can notice that 2r1111 is equal to 2r10000 - 1. So, the sum of the grains on the first 4 squares is 2^5 - 1. You can easily generalize that pattern, of course. Then your program can calculate the answer quickly.
>> > >>
>> > >>
>> > >> [1] The story goes that Gauss' teacher was frustrated with his student's abilities and set him a challenge to occupy him for some time: sum the numbers from 1 through 100. Gauss immediately answered 5,050, much to his teacher's chagrin.
>> > >>
>> > >>> Regards,
>> > >>>
>> > >>> Roelof
>> > >>>
>> > >>>
>> >
>>