(oddSum + evenSum) dividedBy: 10 You previously had _ isDivisibleBy: 10 which certainly works.
Squeak, Pharo, and ST/X have #isDivisibleBy: VisualWorks. Dolphin, and GNU Smalltalk do not. Here's the code from Number.st in ST/X. isDivisibleBy:aNumber "return true, if the receiver can be divided by the argument, aNumber without a remainder. Notice, that the result is only worth trusting, if the receiver is an integer." aNumber = 0 ifTrue: [^ false]. aNumber isInteger ifFalse: [^ false]. ^ (self \\ aNumber) = 0 The comment is wrong: the question makes sense for any combination of exact numbers. When, as in this case, aNumber is a literal integer, all #isDivisibleBy: really adds is overhead. (oddSum + evenSum) \\ 10 = 0 is quite clear, and completely portable. On Fri, 1 May 2020 at 02:16, Roelof Wobben <r.wob...@home.nl> wrote: > > Op 30-4-2020 om 16:06 schreef Richard O'Keefe: > > This sounds very much like the Luhn test task at RosettaCode. > > https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers > > except that there it is described as working on the digits of an > > integer. > > > > (1) There are two approaches to traversing a sequence in reverse. > > (A) Reverse the sequence, then traverse the copy forward. > > aString reverse do: [:each | ...] > > (B) Just traverse the sequence in reverse > > aString reverseDo: [:each | ...] > > My taste is for the second. > > > > (2) There are two approaches to deleting spaces. > > (A) Make a copy of the string without spaces. > > x := aString reject: [:each | each = Character space]. > > x do: ... > > (B) Ignore spaces as you go: > > (i) aString do: [:each | each = Character space ifFalse: [...]] > > (ii) aString select: [:each | each ~= Character space] thenDo: > > [:each | ...] > > > > Combining (1A) and (2A) you get very obvious code: > > (aString reject: [:each | each = Character space]) reverse do: > > [:digit } ...] > > Combining (1B) and (2Bi) you get more efficient code: > > aString reverseDo: [:digit | > > digit = Character space ifFalse: [ ...]] > > > > By the way, let's start by checking that the character in the string *are* > > digits or spaces: > > (aString allSatisfy: [:each | each isDigit or: [each = Character > > s[ace]]) > > ifFalse: [^false], > > > > (3) There are two approaches to doubling the even digits. > > (A) Make a new string that starts as a copy and change every second > > digit from the right. > > (B) Simply *act* as if this has been done; keep track of whether the > > current digit position is even or odd and multiply by 1 or 2 as > > appropriate. > > nextIsOdd := true. > > aString reverseDo: [:digit | > > digit = Character space ifFalse: [ > > nextIsOdd > > ifTrue: [oddSum := ...] > > ifFalse: [evenSum := ...]. > > nextIsOdd := nextIsOdd not]]. > > > > I *like* code that traverses a data structure exactly once and > > allocates no intermediate garbage, so I'd be making (B) choices. > > > > > > For me , I use this to practice solving problems and doing the "right" > steps. > So I love it , that so many people share there way of solving it. > I can learn a lot from it > Expecially when they explain there thinking process so detailed. > > I like this code also a lot. > Am I correct for testing if it is a valid string by doing this ^ > (oddSum + evenSum) dividedBy: 10 > > Roelof >