Day 14: Restroom Redoubt
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
Haskell, alternative approach
The x and y coordinates of robots are independent. 101 and 103 are prime. So, the pattern of x coordinates will repeat every 101 ticks, and the pattern of y coordinates every 103 ticks.
For the first 101 ticks, take the histogram of x-coordinates and test it to see if it’s roughly randomly scattered by performing a chi-squared test using a uniform distrobution as the basis. [That code’s not given below, but it’s a trivial transliteration of the formula on wikipedia, for instance.] In my case I found a massive peak at t=99.
Same for the first 103 ticks and y coordinates. Mine showed up at t=58.
You’re then just looking for solutions of t = 101m + 99, t = 103n + 58 [in this case]. I’ve a library function, maybeCombineDiophantine, which computes the intersection of these things if any exist; again, this is basic wikipedia stuff.
day14b ls = let rs = parse ls size = (101, 103) positions = map (\t -> process size t rs) [0..] -- analyse x coordinates. These should have period 101 xs = zip [0..(fst size)] $ map (\rs -> map (\(p,_) -> fst p) rs & C.count & chi_squared (fst size)) positions xMax = xs & sortOn snd & last & fst -- analyse y coordinates. These should have period 103 ys = zip [0..(snd size)] $ map (\rs -> map (\(p,_) -> snd p) rs & C.count & chi_squared (snd size)) positions yMax = ys & sortOn snd & last & fst -- Find intersections of: t = 101 m + xMax, t = 103 n + yMax ans = do (s,t) <- maybeCombineDiophantine (fromIntegral (fst size), fromIntegral xMax) (fromIntegral (snd size), fromIntegral yMax) pure $ minNonNegative s t in trace ("xs distributions: " ++ show (sortOn snd xs)) $ trace ("ys distributions: " ++ show (sortOn snd ys)) $ trace ("xMax = " ++ show xMax ++ ", yMax = " ++ show yMax) $ trace ("answer could be " ++ show ans) $ ans
I should add - it’s perfectly possible to draw pictures which won’t be spotted by this test, but in this case as it happens the distributions are exceedingly nonuniform at the critical point.
Very cool, taking a statistical approach to discern random noise from picture.
Thanks. It was the third thing I tried - began by looking for mostly-symmetrical, then asked myself “what does a christmas tree look like?” and wiring together some rudimentary heuristics. When those both failed (and I’d stopped for a coffee) the alternative struck me. It seems like a new avenue into the same diophantine fonisher that’s pretty popular in these puzzles - quite an interesting one.
This day’s puzzle is clearly begging for some inventive viaualisations.
Very nice!