It's a good solution.

On Sat, May 2, 2020, 00:52 Roelof Wobben via Pharo-users <
pharo-users@lists.pharo.org> wrote:
> Op 1-5-2020 om 08:35 schreef Roelof Wobben:
> > Op 1-5-2020 om 02:51 schreef Richard O'Keefe:
> >> (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
> >>>
> >
> >
> > oke,
> >
> > so this is better
> >
> > cardNumber := '8273 1232 7352 0569'.
> > oddSum := 0.
> > evenSum := 0.
> > nextIsOdd := false.
> >      cardNumber reverseDo: [:character |
> >           digit := character digitValue.
> >          character = Character space ifFalse: [
> >          nextIsOdd
> >              ifFalse:  [oddSum := oddSum + digit ]
> >              ifTrue: [(digit >= 5 )
> >     ifTrue: [evenSum := evenSum + (digit * 2) - 9 ]
> >     ifFalse: [ evenSum := evenSum + (digit * 2) ]].
> >             nextIsOdd := nextIsOdd not]].
> > ^ evenSum + oddSum // 10 == 0.
> >
> >
> > where I could even make a seperate method of the ifTrue branch when
> > the digit is greater then 5.
> >
> >
> nobody who can say if this is a good solution ?
>
> Roelof
>
>

Reply via email to