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 <b...@openinworld.com> 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 <rao...@gmail.com> 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 <r.wob...@home.nl> 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 >> > > <pharo-users@lists.pharo.org> 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 >> > >> <pharo-users@lists.pharo.org> 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 >> > >>> >> > >>> >> > >>