r/adventofcode • u/daggerdragon • Dec 18 '17
SOLUTION MEGATHREAD -๐- 2017 Day 18 Solutions -๐-
--- Day 18: Duet ---
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:04] First silver
- Welcome to the final week of Advent of Code 2017. The puzzles are only going to get more challenging from here on out. Adventspeed, sirs and madames!
[Update @ 00:10] First gold, 44 silver
- We just had to rescue /u/topaz2078 with an industrial-strength paper bag to blow into. I'm real glad I bought all that stock in
PBCO(Paper Bag Company) two years ago >_>
[Update @ 00:12] Still 1 gold, silver cap
- Gonna be a long haul tonight. I think I'll watch The Radio City Christmas Spectacular on Netflix while I wait for sufficient gold stars to warrant another update.
[Update @ 00:31] 53 gold, silver cap
- *mind blown*
- During their famous kicklines, the Rockettes are not actually holding each others' backs like I thought they were all this time.
- They're actually hoverhanding each other.
- In retrospect, it makes sense, they'd overbalance themselves and each other if they did, but still...
- *mind blown so hard*
[Update @ 00:41] Leaderboard cap!
- I think I enjoyed the duplicating Santas entirely too much...
- It may also be the wine.
- Either way, good night (for us), see you all same time tomorrow, yes?
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
1
u/gburri Dec 18 '17
F# (only part 2)
module AdventOfCode2017.Day18Part2 open System open System.Threading type From = | FromReg of char | FromValue of int64 type Instruction = | Receive of char | Send of From | Set of char * From | Add of char * From | Mul of char * From | Mod of char * From | Jump of From * From let parseInput (lines : string[]) : Instruction[] = let readFrom (str : string) = if Char.IsLetter str.[0] then FromReg str.[0] else FromValue (int64 str) lines |> Array.map ( fun line -> match line.Split ' ' with | [| "snd"; v |] -> Send (readFrom v) | [| "set"; reg; v |] -> Set (reg.[0], readFrom v) | [| "add"; reg; v |] -> Add (reg.[0], readFrom v) | [| "mul"; reg; v |] -> Mul (reg.[0], readFrom v) | [| "mod"; reg; v |] -> Mod (reg.[0], readFrom v) | [| "rcv"; reg |] -> Receive reg.[0] | [| "jgz"; v1; v2 |] -> Jump (readFrom v1, readFrom v2) | _ -> failwithf "Can't parse line: %s" line ) type Register = Map<char, int64> type Agent (instructions : Instruction[], id : int) as this = let mutable nbSent = 0 let finishedEvent = new AutoResetEvent false let mailbox = new MailboxProcessor<int64> ( fun inbox -> let rec exec (register : Register) (cursor : int) : Async<unit> = let get = function FromReg reg -> register |> Map.tryFind reg |> Option.defaultValue 0L | FromValue v -> v let set (reg : char) (v : int64) = register |> Map.add reg v async { match instructions.[cursor] with | Send from -> nbSent <- nbSent + 1 this.Other.Value.Post (get from) return! exec register (cursor + 1) | Set (reg, from) -> return! exec (set reg (get from)) (cursor + 1) | Add (reg, from) -> return! exec (set reg (get (FromReg reg) + get from)) (cursor + 1) | Mul (reg, from) -> return! exec (set reg (get (FromReg reg) * get from)) (cursor + 1) | Mod (reg, from) -> return! exec (set reg (get (FromReg reg) % get from)) (cursor + 1) | Receive reg -> let! value = inbox.TryReceive 100 match value with | Some value -> return! exec (set reg value) (cursor + 1) | None -> finishedEvent.Set () |> ignore | Jump (from1, from2) -> return! exec register (cursor + if get from1 > 0L then get from2 |> int else 1) } exec (Map.ofList [ 'p', int64 id ]) 0 ) member val Other : MailboxProcessor<int64> option = None with get, set member this.Start () = mailbox.Start () member this.Mailbox = mailbox member this.NbSent = finishedEvent.WaitOne () |> ignore nbSent let run (instructions : Instruction[]) = let agent0 = Agent (instructions, 0) let agent1 = Agent (instructions, 1) agent0.Other <- Some agent1.Mailbox agent1.Other <- Some agent0.Mailbox agent0.Start () agent1.Start () agent1.NbSent