summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--day23.fsx115
1 files changed, 115 insertions, 0 deletions
diff --git a/day23.fsx b/day23.fsx
new file mode 100644
index 0000000..3378516
--- /dev/null
+++ b/day23.fsx
@@ -0,0 +1,115 @@
+open System.IO
+
+type Reg = string
+type Lit = int
+type Value =
+    | LiteralVal of literal: Lit
+    | Register of register: Reg
+
+type Instruction =
+    | Cpy of copied: Value * register: Reg
+    | Inc of register: Reg
+    | Dec of register: Reg
+    | Jnz of compared: Value * offset: Value
+    | Tgl of offset: Value
+    | Nop
+
+let parseInstruction (line:string): Instruction =
+    let split = line.Split " "
+    match split[0] with
+    | "inc" -> Inc split[1]
+    | "dec" -> Dec split[1]
+    | "cpy" ->
+        let mutable parsed = 0
+        if (System.Int32.TryParse(split[1], &parsed))
+        then Cpy (LiteralVal parsed, split[2])
+        else Cpy (Register split[1], split[2])
+    | "jnz" -> 
+        let mutable parsed1 = 0
+        if (System.Int32.TryParse(split[1], &parsed1))
+        then
+            let mutable parsed2 = 0
+            if (System.Int32.TryParse(split[2], &parsed2))
+            then Jnz (LiteralVal parsed1, LiteralVal parsed2)
+            else Jnz (LiteralVal parsed1, Register split[2])
+        else 
+            let mutable parsed2 = 0
+            if (System.Int32.TryParse(split[2], &parsed2))
+            then Jnz (Register split[1], LiteralVal parsed2)
+            else Jnz (Register split[1], Register split[2])
+    | "tgl" ->
+        let mutable parsed = 0
+        if (System.Int32.TryParse(split[1], &parsed))
+        then Tgl (LiteralVal parsed)
+        else Tgl (Register split[1])
+    | _ -> Inc ""
+
+let toggleInst (inst: Instruction) : Instruction =
+    match inst with
+    | Inc reg -> Dec reg
+    | Dec reg -> Inc reg
+    | Tgl offset ->
+        match offset with
+        | LiteralVal v-> Nop
+        | Register r -> Inc r
+    | Cpy (copied, register) -> Jnz (copied, Register register)
+    | Jnz (compared, offset) ->
+        match offset with
+        | LiteralVal v-> Nop
+        | Register r -> Cpy (compared, r)
+    | Nop -> Nop
+
+let rec execute index insts registers =
+    if index < 0 || index > (Array.length insts) - 1
+    then 
+        Map.find "a" registers
+    else
+        match insts[index] with
+        | Cpy (value, reg) -> 
+            let copied =
+                match value with
+                | LiteralVal num -> num
+                | Register reg -> Map.find reg registers
+            let newRegisters = Map.change reg (function | Some x -> Some copied | None -> None) registers
+            execute (index + 1) insts newRegisters
+        | Inc reg ->
+            let newRegisters = Map.change reg (function | Some x -> Some (x + 1) | None -> None) registers
+            execute (index + 1) insts newRegisters
+        | Dec reg ->
+            let newRegisters = Map.change reg (function | Some x -> Some (x - 1) | None -> None) registers
+            execute (index + 1) insts newRegisters
+        | Jnz (reg, offset) ->
+            let offset =
+                match offset with
+                | LiteralVal x -> x
+                | Register x -> Map.find x registers
+            let compared =
+                match reg with
+                | LiteralVal num -> num
+                | Register reg -> Map.find reg registers
+            if compared <> 0
+            then 
+                execute (index + offset) insts registers
+            else
+                execute (index + 1) insts registers
+        | Tgl offset ->
+            let offset =
+                match offset with
+                | LiteralVal x -> x
+                | Register x -> Map.find x registers
+            let newIndex = index + offset
+            let newInsts = Array.mapi (fun i v -> 
+                                       match i with
+                                       | _ when i = newIndex -> toggleInst v
+                                       | _ -> v) insts
+            execute (index + 1) newInsts registers
+        | Nop ->
+            execute (index + 1) insts registers
+
+    
+let lines = File.ReadAllLines "day23.txt" |> Array.map parseInstruction
+let regsPart1: Map<string, Lit> = Map.ofList [("a", 7); ("b", 0); ("c", 0); ("d", 0)]
+execute 0 lines regsPart1 |> printfn "%d"
+// analysis of the code indicates it actually calculates reg[a]! + some constant derived from the code
+// in this case, the constant is 90 * 81
+// thus part 2 is 90 * 81 + 12! = 479008890
\ No newline at end of file