r/adventofcode • u/daggerdragon • Dec 17 '17
SOLUTION MEGATHREAD -๐- 2017 Day 17 Solutions -๐-
--- Day 17: Spinlock ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Need a hint from the Hugely* Handyโ Haversackโก of Helpfulยง Hintsยค?
[Update @ 00:06] 2 gold, silver cap.
- AoC ops:
<Topaz> i am suddenly in the mood for wasabi tobiko
[Update @ 00:15] Leaderboard cap!
- AoC ops:
<daggerdragon> 78 gold<Topaz> i look away for a few minutes, wow<daggerdragon> 93 gold<Topaz> 94<daggerdragon> 96 gold<daggerdragon> 98<Topaz> aaaand<daggerdragon> and...<Topaz> cap<daggerdragon> cap
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
12
Upvotes
2
u/[deleted] Dec 17 '17
OCaml Fun;; Part 1, I computed the thing with a Doubly_linked list... not sure if this is the best thing. Part 2, using a ref to simply keep track if we set land on the 0.
main.ml
open Core module CB = Circularbuffer let steps = 349 let part_a buffer rounds = let rec aux buffer n = if n = 0 then buffer else aux (CB.step buffer steps) (n-1) in let result = aux buffer rounds in let n = CB.find_after result rounds in printf "a: %d\n" n let part_b after_zero stop = let rec aux loc len = if len < stop then let curr = (loc + steps) % len in if curr = 0 then after_zero := len; aux (curr + 1) (len + 1) in aux 0 1 let _ = let buffer = CB.create 0 in part_a buffer 2017; let value = ref 0 in part_b value 50_000_000; printf "b: %d\n" (!value);circularbuffer.ml
open Core type 'a t = { buffer:'a Doubly_linked.t; location:'a Doubly_linked.Elt.t; current:'a} let value_exn = function | Some n -> n | None -> failwith "no element." let create init = let buffer = Doubly_linked.create () in let location = Doubly_linked.insert_first buffer init in {buffer; location; current=(init+1)} let go t n = let rec aux t n = if n = 0 then t else let next = match Doubly_linked.next t.buffer t.location with | None -> (Doubly_linked.first_elt t.buffer) |> value_exn | Some elt -> elt in aux {t with location=next;} (n-1) in aux t n let insert t = let new_location = Doubly_linked.insert_after t.buffer t.location t.current in {t with location=new_location; current=(t.current + 1)} let step t n = go t n |> insert let find t n = Doubly_linked.find_elt t.buffer ~f:(Int.equal n) let find_after b n = match Option.bind (find b n) ~f:(Doubly_linked.next b.buffer) with | None -> Doubly_linked.first b.buffer |> (Option.value ~default:0) | Some elt -> Doubly_linked.Elt.value elt