Skip to content

Instantly share code, notes, and snippets.

@object
Created December 8, 2020 06:16
Show Gist options
  • Select an option

  • Save object/c5ab57245faa37294a310e97e0d951ca to your computer and use it in GitHub Desktop.

Select an option

Save object/c5ab57245faa37294a310e97e0d951ca to your computer and use it in GitHub Desktop.
AdventOfCode 2020, December 8
open System
open System.IO
type Instruction =
| Nop of int
| Acc of int
| Jmp of int
let parseLine (line : string) =
let words = line.Split(' ')
match words.[0] with
| "nop" -> Nop (Int32.Parse words.[1])
| "acc" -> Acc (Int32.Parse words.[1])
| "jmp" -> Jmp (Int32.Parse words.[1])
| _ -> failwith "Unexpected"
let instructions =
File.ReadAllLines("input08.txt")
|> Seq.toArray
|> Array.filter (not << String.IsNullOrEmpty)
|> Array.map parseLine
let incrCount idx counts =
match counts |> Map.tryFind idx with
| Some count -> counts |> Map.add idx (count + 1)
| None -> counts |> Map.add idx 1
let rec execute code acc idx counts =
if idx >= Array.length code then
acc
else
match counts |> Map.tryFind idx with
| Some _ -> match acc with | Ok acc -> Error acc | _ -> acc
| None ->
let counts = counts |> incrCount idx
let acc, idx =
match code.[idx] with
| Nop _ -> acc, idx + 1
| Acc n -> (match acc with | Ok acc -> Ok (acc + n) | _ -> acc), idx + 1
| Jmp n -> acc, idx + n
execute code acc idx counts
execute instructions (Ok 0) 0 Map.empty
let swapInstruction (instructions: Instruction array) idx =
let swapped =
match instructions.[idx] with
| Nop n -> Jmp n
| Jmp n -> Nop n
| x -> x
Array.concat [instructions.[0..idx-1]; [|swapped|]; instructions.[idx+1..]]
let rec fix idx =
if idx >= instructions.Length then
Error 0
else
let code = swapInstruction instructions idx
match execute code (Ok 0) 0 Map.empty with
| Ok result ->
Ok result
| Error result ->
fix (idx + 1)
fix 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment