-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday08_part02.fs
80 lines (69 loc) · 3.01 KB
/
day08_part02.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
75
76
77
78
79
80
module day08_part02
open System.Text.RegularExpressions
open AdventOfCode_2016.Modules
type Instruction =
| Rect of columns: int * rows: int
| RotateColumn of column: int * distance: int
| RotateRow of row: int * distance: int
let parseLines (lines: string array) : Instruction list =
let parseRect(line: string) : Instruction =
let pattern = "(?<type>rect|rotate) (((?<column>\d+)x(?<row>\d+))|((?<axis>column|row) (x|y)=(?<index>\d+) by (?<steps>\d+)))"
let regex = new Regex(pattern)
let matches = regex.Match(line)
match matches.Groups["type"].Value with
| "rect" ->
Rect((int)matches.Groups["column"].Value, (int)matches.Groups["row"].Value)
| "rotate" ->
if matches.Groups["axis"].Value = "column" then
RotateColumn((int)matches.Groups["index"].Value, (int)matches.Groups["steps"].Value)
else
RotateRow((int)matches.Groups["index"].Value, (int)matches.Groups["steps"].Value)
| _ -> failwith line
let parseLine (line: string) : Instruction =
parseRect line
lines |> Array.map parseLine |> Array.toList
let printMap (map: string[,]) =
for row in [0..map.GetUpperBound(0) ] do
for column in [0..map.GetUpperBound(1) ] do
printf "%s" map[row, column]
printfn ""
let executeRect (width: int) (tall: int) (map: string[,]) =
for col in [0..width - 1] do
for row in [0..tall - 1] do
map[row, col] <- "█"
let executeRotateColumn (column: int) (distance: int) (map: string[,]) =
let maxRowIdx = map.GetUpperBound(0)
let newColumns = Array.create (maxRowIdx + 1) "."
for row = maxRowIdx downto 0 do
let currentValue = map[row, column]
let newIdx = (row + distance)%(maxRowIdx + 1)
newColumns[newIdx] <- currentValue
newColumns
|> Array.iteri(fun idx v -> map[idx, column] <- v)
let executeRotateRow (row: int) (distance: int) (map: string[,]) =
let maxColumnIdx = map.GetUpperBound(1)
let newRows = Array.create (maxColumnIdx + 1) "."
for column = maxColumnIdx downto 0 do
let currentValue = map[row, column]
let newIdx = (column + distance)%(maxColumnIdx + 1)
newRows[newIdx] <- currentValue
newRows
|> Array.iteri(fun idx v -> map[row, idx] <- v)
let rec runInstructions (instructions: Instruction list) (map: string[,]) =
match instructions with
| instruction::rest ->
match instruction with
| Rect (width,tall) -> executeRect width tall map
| RotateColumn(column, distance) -> executeRotateColumn column distance map
| RotateRow(row, distance) -> executeRotateRow row distance map
runInstructions rest map
| [] -> map
let execute =
let path = "day08/day08_input.txt"
let lines = LocalHelper.GetLinesFromFile(path)
let rows = 6
let columns = 50
let map = Array2D.create rows columns " "
let instructions = parseLines lines
runInstructions instructions map |> ignore
printMap map