diff options
author | Brian Chu <brianmchu42@gmail.com> | 2022-02-21 00:11:06 -0800 |
---|---|---|
committer | Brian Chu <brianmchu42@gmail.com> | 2022-02-21 00:11:06 -0800 |
commit | 0a4fe70d367f0bf1a78602af600052f58a377c34 (patch) | |
tree | 69c2bcd2b54b48968fd52728aaf0e21ca154784c /day18.fsx | |
parent | 1e2642d8793e6a4fb6cba16cd651d5fdca3e4581 (diff) | |
download | AdventOfCode2017-0a4fe70d367f0bf1a78602af600052f58a377c34.tar.gz |
solutions to day 25 main
Diffstat (limited to 'day18.fsx')
-rw-r--r-- | day18.fsx | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/day18.fsx b/day18.fsx new file mode 100644 index 0000000..383519f --- /dev/null +++ b/day18.fsx @@ -0,0 +1,86 @@ +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 = + | Snd of x: Value + | Set of x: Register * y: Value + | Add of x: Register * y: Value + | Mul of x: Register * y: Value + | Mod of x: Register * y: Value + | Rcv of x: Value + | Jgz of x: Value * y: Value + +let resolveValue (value: Value) (registers: Dictionary<string, int64> ) = + 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 "snd ([a-p])" [x] -> Snd (Reg x) + | InstRegex "snd (-?\d+)" [x] -> Snd (Literal (int x)) + | 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 "add ([a-p]) ([a-p])" [x; y] -> Add (x, Reg y) + | InstRegex "add ([a-p]) (-?\d+)" [x; y] -> Add (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 "mod ([a-p]) ([a-p])" [x; y] -> Mod (x, Reg y) + | InstRegex "mod ([a-p]) (-?\d+)" [x; y] -> Mod (x, Literal (int y)) + | InstRegex "rcv ([a-p])" [x] -> Rcv (Reg x) + | InstRegex "rcv (-?\d+)" [x] -> Rcv (Literal (int x)) + | InstRegex "jgz ([a-p]) ([a-p])" [x; y] -> Jgz (Reg x, Reg y) + | InstRegex "jgz ([a-p]) (-?\d+)" [x; y] -> Jgz (Reg x, Literal (int y)) + | InstRegex "jgz (-?\d+) ([a-p])" [x; y] -> Jgz (Literal (int x), Reg y) + | InstRegex "jgz (-?\d+) (-?\d+)" [x; y] -> Jgz (Literal (int x), Literal (int y)) + | x -> printfn "%A" x; failwith "invalid input" + +let rec executeInst (instructions: Instruction array) registers (index: int64) lastSound = + match instructions.[int index] with + | Snd x -> + executeInst instructions registers (index + 1L) (resolveValue x registers) + | Set(x, y) -> + if not (registers.ContainsKey(x)) then registers.[x] <- 0 + registers.[x] <- resolveValue y registers + executeInst instructions registers (index + 1L) lastSound + | Add(x, y) -> + if not (registers.ContainsKey(x)) then registers.[x] <- 0 + registers.[x] <- registers.[x] + resolveValue y registers + executeInst instructions registers (index + 1L) lastSound + | Mul(x, y) -> + if not (registers.ContainsKey(x)) then registers.[x] <- 0 + registers.[x] <- registers.[x] * resolveValue y registers + executeInst instructions registers (index + 1L) lastSound + | Mod(x, y) -> + if not (registers.ContainsKey(x)) then registers.[x] <- 0 + registers.[x] <- registers.[x] % resolveValue y registers + executeInst instructions registers (index + 1L) lastSound + | Rcv x -> + if (resolveValue x registers) > 0 then lastSound else executeInst instructions registers (index + 1L) lastSound + | Jgz(x, y) -> + if (resolveValue x registers) > 0 then + executeInst instructions registers (index + resolveValue y registers) lastSound + else + executeInst instructions registers (index + 1L) lastSound + +let () = + let registers = new Dictionary<string, int64>() + let input = File.ReadAllLines "day18.txt" |> Array.map parseValue + let recovered = executeInst input registers 0 0 + printfn "%A" recovered \ No newline at end of file |