Spent a huge amount of time to understand why Ada.Integer_Text_IO.Get is unable to read a value from 0: string . As always I forgot about deprecated integer format, where # could b replaced by :. Isn’t time to get rid of this in 2022?
Wow. For once I didnt bother with parsing input; it was short, so I said to myself, “Let’s include it directly.” I later wondered whether that was a good idea, but seeing your post, maybe so!
As a mathematician I’m embarrassed to confess that my stumbling block was not noticing that part 2 simply requires modular arithmetic, so I wasted far too much time re-learning the Big_Integer crate, which turned out to be too small anyway!
I have considered that way seriously, but for some reason I wanted to solve the problem with HAC which hasn’t aggregates, so I went for a parser for which there is a draft that can be easily adapted. Later I’ve realized that HAT (HAC’s embedded toolbox package) didn’t have a Delete procedure for removing a part of a variable-size string. This shocking omission is fixed now .
-- transcribing this might not be the best idea I ever had,
-- but it saved me the trouble of writing a parser
:= ( if Doing_Example then (
0 => (
Items => ( 79, 98, others => 0 ),
Next_Free => 3,
Operation => Multiply,
Operand => 19,
Test => 23,
Dest_True => 2,
Dest_False => 3,
Items_Inspected => 0
1 => (
Items => ( 54, 65, 75, 74, others => 0 ),
Next_Free => 5,
So Monkey 0 has items 79 and 98; your interest is multiplied by 19 when he inspects an item, he tests your interest by dividing by 23; if divisible, he sends it to Monkey 2; otherwise, to Monkey 3, and at the outset has inspected 0 items.
This is the first example monkey; the puzzle monkeys were defined in the else clause.
As @zertovitch points out, I defined a proper operation Square, and in that case the “processor” ignores the value of Operand. I didn’t think at the time about making a discriminated record, the way someone else who also defined an enumeration did. I should have done that, and if I go revise my solution I probably will. I was thinking of adding a parser, anyway.
I’m not a mathematician, but I have a quite good background on math. I had the intuition that new Worry_Level that results from a Monkey inspection can be transformed modulo the LCM (least common multiple) of all division test numbers the troop is using. So before throwing the item I applied this operation … and it worked! But I don’t remember which is the number property or theorem for a good explanation to be based on. I simply thought that “anything that happens with Items in [0, N] (N=LCM-1) is also happening in [k*N, (k+1)*N]”. Is there a better explanation? or, Is there a better way to solve this puzzle?
I think you were actually thinking the converse; that is, “anything that happens with Items in [k*N, (k+1)*N] (N=LCM-1) is also happening in [0, N]”.
That’s essentially the idea, adding the caveat that “anything” (a very broad term) might not happen in the more general case where the divisibility involves numbers that are not relatively prime to each other. For example.
No, I wasn’t My analysis was more basic and was like “Item values are quite low at the beginning, so there must be a way to keep them low modulo something in the next iterations; to keep them in [0,N], and because all monkeys are making divisibility tests, what about the LCM of them all?” … again, that was an intuition, not a mathematical reasoning
Thanks for the link, didn’t remember that theorem, neither know its extension to co-prime numbers … I didn’t notice that the test numbers used by monkeys are all primes.
Regarding the old + old case, I did an implementation that supports it, just is case …