-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDay6.fs
More file actions
103 lines (80 loc) · 2.93 KB
/
Day6.fs
File metadata and controls
103 lines (80 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
module Day6
open System
open System.IO
open System.Collections.Generic
type MathOperator =
| Addition
| Multiplication
module MathOperator =
let isOperator (c: char) = c = '+' || c = '*'
let fromString (c: string) =
match c with
| "+" -> Addition
| "*" -> Multiplication
| _ -> failwith "Unsupported operation"
let fromChar (c: char) =
match c with
| '+' -> Addition
| '*' -> Multiplication
| _ -> failwith "Unsupported operation"
type MathExpression =
{ operator: MathOperator
operands: int64 array }
module MathExpression =
let perform (expression: MathExpression) =
match expression.operator with
| Addition -> expression.operands |> Array.sum
| Multiplication -> expression.operands |> Array.reduce (*)
let sumOfMathExpressions expressions =
expressions |> Array.sumBy MathExpression.perform
let parseAsHuman filename =
let parsed =
filename
|> File.ReadAllLines
|> Array.map _.Split(" ", StringSplitOptions.RemoveEmptyEntries)
[| for column in parsed[0].Length - 1 .. -1 .. 0 do
let row = [| for row in 0 .. parsed.Length - 1 -> parsed[row][column] |]
let operator = MathOperator.fromString row[row.Length - 1]
let operands = row |> Array.take (row.Length - 1) |> Array.map int64
yield
{ operator = operator
operands = operands } |]
let parseAsCephalopod filename : MathExpression array =
let parsed = filename |> File.ReadAllLines
let maxCols = parsed |> Array.map _.Length |> Array.max
let expressions = List<MathExpression>()
let mutable operands = List<int64>()
for column in maxCols - 1 .. -1 .. 0 do
let chars = List<char>()
let mutable operator = None
for row in 0 .. parsed.Length do
if row = parsed.Length then
if chars.Count > 0 then
operands.Add(String(chars.ToArray()) |> int64)
if operator.IsSome then
expressions.Add(
{ operator = operator.Value
operands = operands.ToArray() }
)
operands.Clear()
elif column < parsed[row].Length then
let c = parsed[row][column]
if c |> MathOperator.isOperator then
operator <- Some(c |> MathOperator.fromChar)
elif c <> ' ' then
chars.Add(c)
expressions.ToArray()
module Tests =
open Xunit
[<Theory>]
[<InlineData("Inputs/Day6/test.txt", 4277556)>]
[<InlineData("Inputs/Day6/input.txt", 4805473544166L)>]
let ``Part 1: The sum of all math problems`` (filename: string, expected: int64) =
let result = filename |> parseAsHuman |> sumOfMathExpressions
Assert.Equal(expected, result)
[<Theory>]
[<InlineData("Inputs/Day6/test.txt", 3263827)>]
[<InlineData("Inputs/Day6/input.txt", 8907730960817L)>]
let ``Part 2: The sum of all math problems with cephalopod math`` (filename: string, expected: int64) =
let result = filename |> parseAsCephalopod |> sumOfMathExpressions
Assert.Equal(expected, result)