From 0a4fe70d367f0bf1a78602af600052f58a377c34 Mon Sep 17 00:00:00 2001 From: Brian Chu Date: Mon, 21 Feb 2022 00:11:06 -0800 Subject: solutions to day 25 --- day23.fsx | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 day23.fsx (limited to 'day23.fsx') diff --git a/day23.fsx b/day23.fsx new file mode 100644 index 0000000..5714fad --- /dev/null +++ b/day23.fsx @@ -0,0 +1,84 @@ +open System.IO +open System.Collections.Generic +open System.Text.RegularExpressions + +type Register = string +type Value = + | Literal of int64 + | Reg of Register + +let (|InstRegex|_|) pattern string = + let m = Regex(pattern).Match(string) + if m.Success then + Some(List.tail [for g in m.Groups -> g.Value]) + else None + +type Instruction = + | Set of x: Register * y: Value + | Sub of x: Register * y: Value + | Mul of x: Register * y: Value + | Jnz of x: Value * y: Value + +let resolveValue (value: Value) (registers: Dictionary ) = + let tryGetDefaultRegister key = + if not (registers.ContainsKey(key)) then registers.[key] <- 0L + registers.[key] + + match value with + | Literal x -> x + | Reg x -> tryGetDefaultRegister x + +let parseValue line = + match line with + | InstRegex "set ([a-p]) ([a-p])" [x; y] -> Set (x, Reg y) + | InstRegex "set ([a-p]) (-?\d+)" [x; y] -> Set (x, Literal (int y)) + | InstRegex "sub ([a-p]) ([a-p])" [x; y] -> Sub (x, Reg y) + | InstRegex "sub ([a-p]) (-?\d+)" [x; y] -> Sub (x, Literal (int y)) + | InstRegex "mul ([a-p]) ([a-p])" [x; y] -> Mul (x, Reg y) + | InstRegex "mul ([a-p]) (-?\d+)" [x; y] -> Mul (x, Literal (int y)) + | InstRegex "jnz ([a-p]) ([a-p])" [x; y] -> Jnz (Reg x, Reg y) + | InstRegex "jnz ([a-p]) (-?\d+)" [x; y] -> Jnz (Reg x, Literal (int y)) + | InstRegex "jnz (-?\d+) ([a-p])" [x; y] -> Jnz (Literal (int x), Reg y) + | InstRegex "jnz (-?\d+) (-?\d+)" [x; y] -> Jnz (Literal (int x), Literal (int y)) + | x -> printfn "%A" x; failwith "invalid input" + +let rec executeInst (instructions: Instruction array) (registers: Dictionary) (index: int64) mulCount = + if (int index) >= Array.length instructions || (int index) < 0 then mulCount + else + match instructions.[int index] with + | Set(x, y) -> + if not (registers.ContainsKey(x)) then registers.[x] <- 0 + registers.[x] <- resolveValue y registers + executeInst instructions registers (index + 1L) mulCount + | Sub(x, y) -> + if not (registers.ContainsKey(x)) then registers.[x] <- 0 + registers.[x] <- registers.[x] - resolveValue y registers + executeInst instructions registers (index + 1L) mulCount + | Mul(x, y) -> + if not (registers.ContainsKey(x)) then registers.[x] <- 0 + registers.[x] <- registers.[x] * resolveValue y registers + executeInst instructions registers (index + 1L) (mulCount + 1) + | Jnz(x, y) -> + if (resolveValue x registers) <> 0 then + executeInst instructions registers (index + resolveValue y registers) mulCount + else + executeInst instructions registers (index + 1L) mulCount + +let part1() = + let registers = new Dictionary() + let input = File.ReadAllLines "day23.txt" |> Array.map parseValue + let mulCount = executeInst input registers 0 0 + printfn "%A" mulCount + +// i knew it couldn't be that easy :( +// time to decompile the assembly and figure out what's happening + +// let part2() = +// let registers = new Dictionary() +// registers.["a"] <- 1 +// let input = File.ReadAllLines "day23.txt" |> Array.map parseValue +// executeInst input registers 0 0 |> ignore +// printfn "%A" registers.["h"] + +let () = + part1() \ No newline at end of file -- cgit 1.4.1-2-gfad0