On Day 15 we are working with number generators. We have two generators that start with given numbers as input. In each iteration, generator multiplies its value by fixed number and keeps the reminder of diving by 2147483647.
We need to count how many times lowest 16 bits matched for both generators after 40 million iterations.
Here is the solution:
a = 65 b = 8921 count = 0 40_000_000.times do a = (a * 16807) % 2147483647 b = (b * 48271) % 2147483647 if a & 0xffff == b & 0xffff count += 1 end end puts count
b are the starting numbers given as input. The solution is trivial, we just iterate 40 million times and count how many times values matched (16 lowest bits). Maybe not optimal solution, but runs in 2-3 seconds so I think it is fine.
In the second part the rules are a bit different. Generators still generate numbers in the same way, but generator A only hands down numbers divisible by 4 and generator B numbers divisible by 8. This means that when one generator has valid number another one may not have anything to compare to.
We need to store results from both generators and only compare numbers when we have results from both. Here is the solution:
a = 65 b = 8921 count = 0 a_values =  b_values =  iterations = 0 while true a = (a * 16807) % 2147483647 b = (b * 48271) % 2147483647 a_values.push(a) if a % 4 == 0 b_values.push(b) if b % 8 == 0 while a_values.size > 0 && b_values.size > 0 a_val = a_values.shift b_val = b_values.shift iterations += 1 if a_val & 0xffff == b_val & 0xffff count += 1 end if iterations >= 5_000_000 break end end if iterations >= 5_000_000 break end end puts count
We are storing results in two different arrays and only when both have values we compare them. This is again maybe not optimal solution, but 4 seconds seems fine to me. I think there are some arithmetic tricks you can do to get faster answers, but didn’t have time to figure it out. Yet.