[Cuis-dev] feedback on simple code
Andres Valloud
ten at smallinteger.com
Wed Jun 5 15:37:04 PDT 2024
Hi, ifTrue: is supposed to take a block argument, so it should be
ifTrue: [nil]. And to prevent indenting the entire method, consider
self < 1 ifTrue: [^nil].
... etc...
^seq
It's perfectly fine to have multiple return statements.
By the way, use // 2 instead of / 2, because / 2 will try to make a
fraction to then discover that next was even. But now you know next is
even, so you can do next // 2. Using / is still correct of course.
I wouldn't worry about doing bitShift: -1 instead of // 2 here. That
kind of "speedup" is barking at the wrong forest (not even the wrong
tree) from the perspective of Collatz. I would familiarize myself with
the difference between the pairs "//, \\", "quo:, rem:", and "div:,
mod:", however.
On 6/5/24 11:16 AM, Mark Volkmann via Cuis-dev wrote:
> I took another shot at simplifying the code. I didn't need to use
> recursion. I can do this instead as an instance method added to the
> Integer class:
>
> collatz
> "answers an OrderedCollection containing the Collatz sequence for
> this integer"
>
> | next seq |
> ^self < 1
> ifTrue: nil
> ifFalse: [
> next := self.
> seq := OrderedCollection new.
> seq addLast: next.
> [next = 1] whileFalse: [
> next := next even ifTrue: [next / 2] ifFalse: [next * 3 + 1].
> seq addLast: next
> ].
> ^seq
> ]
>
> Beside the lack of memoization and the "orbit" concept, what would you
> change about this?
>
>
> On Wed, Jun 5, 2024 at 12:40 PM Mark Volkmann <r.mark.volkmann at gmail.com
> <mailto:r.mark.volkmann at gmail.com>> wrote:
>
> See my replies inline below with some parts snipped to focus my replies.
>
> On Wed, Jun 5, 2024 at 12:19 PM Andres Valloud via Cuis-dev
> <cuis-dev at lists.cuis.st <mailto:cuis-dev at lists.cuis.st>> wrote:
>
> Always be on the lookout for when a receiver is just self.
> Otherwise,
> the code is not using the knowledge it has of where it is
> implemented
> (and this leads to all sorts of problems later).
>
>
> Ah! I did not know that I could use `self` to refer to the class in
> a class method.
>
> Also, you can accomplish the same with much less code. Any time
> you
> have a class whose class methods offer a "service" but do not
> really
> have instances, you should suspect the code should be placed
> elsewhere.
>
>
> I see that I don't need the next: method and can just move that code
> in the gather:seq: method.
> But it's not apparent to me what else I can do to make the code shorter.
>
> Side comment: I've been working on the Collatz problem for a *long*
> time, so I have quite a few opinions on how to go about writing
> specifically this code...
>
>
> I know I could add caching of results to make subsequent calls with
> different integers much faster.
>
> But in this particular case, what you're collecting is the orbit
> of an
> integer (so, anInteger, not aNumber).
>
>
> Excellent point! I changed every occurrence of `aNumber` to
> `anInteger` in my code.
>
> --
> R. Mark Volkmann
> Object Computing, Inc.
>
>
>
> --
> R. Mark Volkmann
> Object Computing, Inc.
>
More information about the Cuis-dev
mailing list