From 220274d5d3e5c9534de2322cc8158a040d994246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Gergely?= Date: Sun, 29 Dec 2024 23:54:30 +0100 Subject: [PATCH] Day 7 Part 1 --- Kodfodrasz.AoC.Year2024.Tests/Day7Tests.fs | 95 +++++++++++++++++++ .../Kodfodrasz.AoC.Year2024.Tests.fsproj | 1 + Kodfodrasz.AoC.Year2024/Day7.fs | 75 +++++++++++++++ .../Kodfodrasz.AoC.Year2024.fsproj | 1 + 4 files changed, 172 insertions(+) create mode 100644 Kodfodrasz.AoC.Year2024.Tests/Day7Tests.fs create mode 100644 Kodfodrasz.AoC.Year2024/Day7.fs diff --git a/Kodfodrasz.AoC.Year2024.Tests/Day7Tests.fs b/Kodfodrasz.AoC.Year2024.Tests/Day7Tests.fs new file mode 100644 index 0000000..35f2908 --- /dev/null +++ b/Kodfodrasz.AoC.Year2024.Tests/Day7Tests.fs @@ -0,0 +1,95 @@ +module Kodfodrasz.AoC.Year2024.Tests.Day7Tests + +open Xunit +open Swensen.Unquote.Assertions + +open Kodfodrasz.AoC +open Kodfodrasz.AoC.Year2024 +open Kodfodrasz.AoC.Year2024.Day7 + + +let exampleInput = """ +190: 10 19 +3267: 81 40 27 +83: 17 5 +156: 15 6 +7290: 6 8 6 15 +161011: 16 10 13 +192: 17 8 14 +21037: 9 7 18 13 +292: 11 6 16 20 + """ + +[] +let ``Parsing example input`` () = + let expected = [ + { + TestValue = 190L + Terms = [10L; 19L] + } + { + TestValue = 3267L + Terms = [81L; 40L; 27L] + } + { + TestValue = 83L + Terms = [17L; 5L] + } + { + TestValue = 156L + Terms = [15L; 6L] + } + { + TestValue = 7290L + Terms = [6L; 8L; 6L; 15L] + } + { + TestValue = 161011L + Terms = [16L; 10L; 13L] + } + { + TestValue = 192L + Terms = [17L; 8L; 14L] + } + { + TestValue = 21037L + Terms = [9L; 7L; 18L; 13L] + } + { + TestValue = 292L + Terms = [11L; 6L; 16L; 20L] + } + ] + + test + <@ let actual = parseInput exampleInput + actual = Ok expected @> + +[] +let ``Answer 1 helper function: check`` () = + let input = parseInput exampleInput |> Result.get + + test <@ true = Day7.check input[0] @> + test <@ true = Day7.check input[1] @> + test <@ false = Day7.check input[3] @> + test <@ false = Day7.check input[5] @> + test <@ true = Day7.check input[8] @> + + +[] +let ``Answer 1 for example input`` () = + let input = parseInput exampleInput + + test + <@ let actual = Result.bind answer1 input + let expected: Result<_, string> = Ok 3749L + actual = expected @> + +[] +let ``Answer 2 for example input`` () = + let input = parseInput exampleInput + + test + <@ let actual = Result.bind answer2 input + let expected: Result<_, string> = Ok 31 + actual = expected @> diff --git a/Kodfodrasz.AoC.Year2024.Tests/Kodfodrasz.AoC.Year2024.Tests.fsproj b/Kodfodrasz.AoC.Year2024.Tests/Kodfodrasz.AoC.Year2024.Tests.fsproj index 6497011..5785713 100644 --- a/Kodfodrasz.AoC.Year2024.Tests/Kodfodrasz.AoC.Year2024.Tests.fsproj +++ b/Kodfodrasz.AoC.Year2024.Tests/Kodfodrasz.AoC.Year2024.Tests.fsproj @@ -11,6 +11,7 @@ + diff --git a/Kodfodrasz.AoC.Year2024/Day7.fs b/Kodfodrasz.AoC.Year2024/Day7.fs new file mode 100644 index 0000000..87621b7 --- /dev/null +++ b/Kodfodrasz.AoC.Year2024/Day7.fs @@ -0,0 +1,75 @@ +module Kodfodrasz.AoC.Year2024.Day7 + +open System +open System.Text.RegularExpressions +open Kodfodrasz.AoC + +type CalibrationEquation = { + TestValue : int64 + Terms: int64 list +} + +type parsedInput = CalibrationEquation list +let parseInput (input: string): Result = + let matchesEquatons= Regex.Matches( + input, + @"^\s*(?\d+):(?:\s+(?\d+))+\s*$", + RegexOptions.Multiline) + + let matchedEquations = + let parseRule (m:Match) = + let tv = m.Groups["testvalue"].Value |> int64 + let terms = + m.Groups["n"].Captures + |> Seq.map (fun (c:Capture) -> c.Value |> int64) + |> Seq.toList + + { + TestValue = tv + Terms = terms + } + + matchesEquatons + |> Seq.map parseRule + |> Seq.toList + + Ok matchedEquations + +let check (eqn : CalibrationEquation) = + let rec check goal acc terms = + match terms with + | [] -> goal = acc + | head :: tail -> + if acc > goal then false + else + if (check goal (acc + head) tail) then + true + else + check goal (acc * head) tail + match eqn.Terms with + | [] -> false + | h :: t -> check eqn.TestValue h t + +let answer1 (data : parsedInput) = + data + |> List.toArray + |> Array.Parallel.filter check + |> Array.sumBy(fun eqn -> eqn.TestValue) + |> Ok + +let answer2 (data : parsedInput) = + failwith "TODO" + +type Solver() = + inherit SolverBase("Bridge Repair") + with + override this.Solve input = + input + |> + this.DoSolve + (parseInput) + [ + answer1; + answer2; + ] + diff --git a/Kodfodrasz.AoC.Year2024/Kodfodrasz.AoC.Year2024.fsproj b/Kodfodrasz.AoC.Year2024/Kodfodrasz.AoC.Year2024.fsproj index 28ce3e8..f7c45ed 100644 --- a/Kodfodrasz.AoC.Year2024/Kodfodrasz.AoC.Year2024.fsproj +++ b/Kodfodrasz.AoC.Year2024/Kodfodrasz.AoC.Year2024.fsproj @@ -11,6 +11,7 @@ +