aboutsummaryrefslogtreecommitdiff
path: root/aoc-2022-dotnet
diff options
context:
space:
mode:
authorTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2022-12-28 20:33:21 +0100
committerTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2022-12-28 20:33:21 +0100
commitac81191905118139c5461ee552c1ee06e4f8544b (patch)
treecccb81ff845dfa9d0655545aa02dd04bf39072df /aoc-2022-dotnet
parent8e71f049f5ffce904fcd477dbb019e794391c595 (diff)
downloadgleam_aoc2020-ac81191905118139c5461ee552c1ee06e4f8544b.tar.gz
gleam_aoc2020-ac81191905118139c5461ee552c1ee06e4f8544b.zip
Finish day 21
Diffstat (limited to 'aoc-2022-dotnet')
-rw-r--r--aoc-2022-dotnet/Day21/Program.fs108
-rw-r--r--aoc-2022-dotnet/README.md4
2 files changed, 71 insertions, 41 deletions
diff --git a/aoc-2022-dotnet/Day21/Program.fs b/aoc-2022-dotnet/Day21/Program.fs
index 3837054..f9a608d 100644
--- a/aoc-2022-dotnet/Day21/Program.fs
+++ b/aoc-2022-dotnet/Day21/Program.fs
@@ -1,61 +1,91 @@
module Day21
open System.IO
+open System.Numerics
open FSharpPlus
open FParsec
open Common
type MonkeyName = string
-type Operator = int64 -> int64 -> int64
+
+module MonkeyName =
+ let root = "root"
+ let human = "humn"
+
+type Operator = Complex -> Complex -> Complex
+
+module Operator =
+ let fromChar =
+ function
+ | '+' -> (+)
+ | '-' -> (-)
+ | '*' -> (*)
+ | '/' -> (/)
+ | c -> failwithf "Invalid operator: %c" c
+
+ let unknownExtractor l r =
+ let eq: Complex = l - r
+ Complex(round <| -eq.Real / eq.Imaginary, 0)
type MonkeyJob =
- | Number of int64
+ | Number of Complex
| Operation of MonkeyName * Operator * MonkeyName
+ static member unknownVariable = Number(Complex(0, 1))
+
+ static member eval(cache: Map<MonkeyName, Complex>) =
+ function
+ | Number num -> num
+ | Operation (left, operator, right) -> operator cache[left] cache[right]
+
+ static member withOperator op =
+ function
+ | Operation (l, _, r) -> Operation(l, op, r)
+ | other -> other
+
static member dependencies =
function
- | Number _ -> []
| Operation (l, _, r) -> [ l; r ]
+ | _ -> []
type Monkey = MonkeyName * MonkeyJob
-let charToOperator =
- function
- | '+' -> (+)
- | '-' -> (-)
- | '*' -> (*)
- | '/' -> (/)
- | c -> failwithf "Invalid operator: %c" c
-
-let parseMonkey =
- let pspc = pchar ' '
- let pname = anyString 4 |>> MonkeyName
- let poper = pspc >>. anyChar .>> pspc |>> charToOperator
- let pnumber = pint64 |>> Number
- let poperation = tuple3 pname poper pname |>> Operation
- let pjob = pnumber <|> poperation
- let pmonkey = pname .>> pstring ": " .>>. pjob |>> Monkey
- Util.parse pmonkey
-
-let solution input =
- let monkeys = input |> Seq.map parseMonkey |> Map.ofSeq
-
- monkeys
- |> Map.mapValues MonkeyJob.dependencies
- |> Util.tsort
- |> List.fold
- (fun values name ->
- Map.add
- name
- (match monkeys[name] with
- | Number num -> num
- | Operation (left, operator, right) -> operator values[left] values[right])
- values)
- Map.empty
- |> Map.find "root"
+module Monkey =
+ let parse =
+ let pws = pchar ' '
+ let pname = anyString 4 |>> MonkeyName
+ let pop = pws >>. anyChar .>> pws |>> Operator.fromChar
+ let pnumber = pfloat |>> (fun n -> Number(Complex(n, 0)))
+ let poperation = tuple3 pname pop pname |>> Operation
+ let pjob = pnumber <|> poperation
+ let pmonkey = pname .>> pstring ": " .>>. pjob |>> Monkey
+ Util.parse pmonkey
+
+let solution modification input =
+ let monkeys =
+ input
+ |> Seq.map Monkey.parse
+ |> Map.ofSeq
+ |> modification
+
+ let nodeValues =
+ monkeys
+ |> Map.mapValues MonkeyJob.dependencies
+ |> Util.tsort
+ |> List.fold (fun cache name -> Map.add name (MonkeyJob.eval cache monkeys[name]) cache) Map.empty
+
+ int64 nodeValues[MonkeyName.root].Real
+
+let part1 = id
+
+let part2 =
+ Map.add MonkeyName.human MonkeyJob.unknownVariable
+ >> Map.change MonkeyName.root (Option.map (MonkeyJob.withOperator Operator.unknownExtractor))
let test = File.ReadLines("test.txt")
-assert (solution test = 152)
+assert (solution part1 test = 152)
+assert (solution part2 test = 301)
let input = File.ReadLines("input.txt")
-printfn "%d" <| solution input
+printfn "%d" <| solution part1 input
+printfn "%d" <| solution part2 input
diff --git a/aoc-2022-dotnet/README.md b/aoc-2022-dotnet/README.md
index bc6029a..37de967 100644
--- a/aoc-2022-dotnet/README.md
+++ b/aoc-2022-dotnet/README.md
@@ -1,6 +1,6 @@
# Advent of Code 2022 in F#
![F#](https://img.shields.io/badge/F%23-grey?logo=.NET)
-![Stars](https://img.shields.io/badge/🌟%20stars-38/50-orange)
+![Stars](https://img.shields.io/badge/🌟%20stars-40/50-orange)
| Day | Problem Name | Part 1 | Part 2 | Practiced Concepts |
| :----: | ---------------------------------------------------------------- | :----: | :----: | ---------------------------------------------------- |
@@ -24,7 +24,7 @@
| **18** | [Boiling Boulders](https://adventofcode.com/2022/day/18) | :star: | :star: | functional DFS, 3D vectors, position bound checking |
| **19** | [Not Enough Minerals](https://adventofcode.com/2022/day/19) | | | |
| **20** | [Grove Positioning System](https://adventofcode.com/2022/day/20) | :star: | :star: | linked lists, modulo & remainder |
-| **21** | [Monkey Math](https://adventofcode.com/2022/day/21) | | | |
+| **21** | [Monkey Math](https://adventofcode.com/2022/day/21) | :star: | :star: | topological sort, ADTs, complex numbers |
| **22** | [Monkey Map](https://adventofcode.com/2022/day/22) | | | |
| **23** | [Unstable Diffusion](https://adventofcode.com/2022/day/23) | | | |
| **24** | [Blizzard Basin](https://adventofcode.com/2022/day/24) | | | |