"if I use do:���� this ends at the end of the array."
True.�� But all that means is that you have to keen on using #do:.
Processing an array repeatedly is as simple as
�� [true] whileTrue: [
�� �� anArray do: [:each |
�� �� �� ...]]
I had intended to twist this into
�� [changes anySatisfy: [:change | ...]] whileFalse.
However, in this case your second alternative has much to recommend it.
The control flow is simple.�� There's no magic about it.�� It's an
unusual setup, so no need to get fancy.
�� seen := Set new.
�� frequency := 0.
�� found := false.
�� i := changes size.
�� [found] whileFalse: [
�� �� i := i = changes size ifTrue: [1] ifFalse: [i+1].
�� �� frequency := frequency��+ (changes at: i).
�� �� found := seen includes: frequency.
�� �� seen add: frequency].
I like this better than what I had.
If we _were_ to get fancy, then introducing a CyclicReadStream
class and doing
�� �� seen := Set new.
�� �� frequency := 0.
�� �� found := false.
�� �� stream := CyclicReadStream on: self changes.
�� �� [found] whileFalse: [
�� �� �� frequency := frequency��+ stream next.
�� �� �� found := seen includes: frequency.
�� �� �� seen add: frequency].
wouldn't shrink the code much.�� Oddly enough, I've encountered
problems in previous Advent of Code exercises where CyclicReadStream
would have been handy.�� But just for this case?�� No.