-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.fs
74 lines (59 loc) · 2.26 KB
/
Program.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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
module Day08
open System
open System.IO
open System.Text.RegularExpressions
type Instruction =
| Rect of int * int
| RotateRow of int * int
| RotateCol of int * int
let (|Regex|_|) pattern input =
let m = Regex.Match(input, pattern)
if m.Success
then Some(List.tail [ for g in m.Groups -> g.Value ])
else None
let parseInstruction instruction =
match instruction with
| Regex @"rect (\d+)x(\d+)" [w; h] -> Rect (int w, int h)
| Regex @"rotate row y=(\d+) by (\d+)" [row; diff] -> RotateRow (int row, int diff)
| Regex @"rotate column x=(\d+) by (\d+)" [col; diff] -> RotateCol (int col, int diff)
| _ -> failwithf "Invalid instruction: %s" instruction
type Display(width: int, height: int) =
let mutable grid = Array.init height (fun _ -> Array.init width (fun _ -> 0))
member this.drawRect w h =
for row in 0 .. h - 1 do
for col in 0 .. w - 1 do
grid.[row].[col] <- 1
member this.rotateRow row amount =
let originalRow = Array.copy grid.[row]
for i in 0 .. width - 1 do
let j = (i + amount) % width
grid.[row].[j] <- originalRow.[i]
member this.rotateCol col amount =
let originalCol = grid |> Array.map (fun row -> row.[col])
for i in 0 .. height - 1 do
let j = (i + amount) % height
grid.[j].[col] <- originalCol.[i]
member this.eval instruction =
match instruction with
| Rect (w, h) -> this.drawRect w h
| RotateRow (row, amount) -> this.rotateRow row amount
| RotateCol (col, amount) -> this.rotateCol col amount
member this.voltage () =
grid |> Array.sumBy (Array.sum)
member this.draw () =
grid
|> Array.map (Array.map (fun col -> if col = 1 then '#' else '.'))
|> Array.map String
|> Array.map (sprintf "%s\n")
|> Array.fold (+) ""
[<EntryPoint>]
let main argv =
let input =
File.ReadLines("Input.txt")
|> Seq.map parseInstruction
|> Seq.toList
let display = new Display(50, 6)
List.iter display.eval input
printfn "Part one: %d" (display.voltage())
printfn "Part two:\n%s" (display.draw())
0