-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day22.fs
58 lines (45 loc) · 1.25 KB
/
Day22.fs
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
module AoC2021.Day22
open System.Runtime.InteropServices
open AoC2021.Utils
let clipWithin min max coordPair =
coordPair
|> (fun (c1, c2) -> List.max [ c1; min ], List.min [ c2; max ])
type Instruction =
| On
| Off
let parseCoordinate cs =
cs
|> splitS "\.\."
|> Seq.map int
|> List.ofSeq
|> fun [ c1; c2 ] -> (c1, c2)
let parseInstruction row =
let [ inst; coordinateData ] = (row |> split ' ' |> List.ofSeq)
let inst' =
inst
|> (function
| "on" -> On
| "off" -> Off)
let coords =
split ',' coordinateData
|> Seq.map (split '=' >> Seq.last >> parseCoordinate >> clipWithin -50 50)
inst', coords
let coordsToRange = Seq.map (fun (c1, c2) -> [ c1 .. c2 ])
let toTuple [ x; y; z ] = x, y, z
let getAllCubes =
coordsToRange
>> List.ofSeq
>> cartesian
>> Seq.map toTuple
>> Set.ofSeq
let turnOnOrOff state (instr, coords) =
match instr with
| On -> Set.union state (getAllCubes coords)
| Off -> Set.difference state (getAllCubes coords)
let day22 fn () =
let input = readInput fn
let instructions = input |> Seq.map parseInstruction
instructions
|> Seq.fold turnOnOrOff Set.empty<int * int * int>
|> Set.count
|> int64