-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
131 lines (113 loc) · 2.23 KB
/
main.go
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package main
import (
"fmt"
"io"
"os"
"strings"
"github.com/devries/advent_of_code_2021/utils"
"github.com/spf13/pflag"
)
func main() {
pflag.Parse()
f, err := os.Open("../inputs/day13.txt")
utils.Check(err, "error opening input.txt")
defer f.Close()
r := solve(f)
fmt.Println(r)
}
func solve(r io.Reader) string {
lines := utils.ReadLines(r)
pts, folds := parseSheet(lines)
for _, fold := range folds {
fold.do(pts)
}
maxX := 0
maxY := 0
for k := range pts {
if k.X > maxX {
maxX = k.X
}
if k.Y > maxY {
maxY = k.Y
}
}
if utils.Verbose {
for j := 0; j <= maxY; j++ {
for i := 0; i <= maxX; i++ {
if pts[utils.Point{X: i, Y: j}] {
fmt.Printf("\u2588")
} else {
fmt.Printf(" ")
}
}
fmt.Printf("\n")
}
}
var sb strings.Builder
for j := 0; j <= maxY; j++ {
for i := 0; i <= maxX; i++ {
if pts[utils.Point{X: i, Y: j}] {
sb.WriteRune('#')
} else {
sb.WriteRune('.')
}
}
sb.WriteRune('\n')
}
res := utils.OCRLetters(sb.String())
return res
}
type Fold struct {
Orientation rune
Position int
}
func (f Fold) do(pts map[utils.Point]bool) {
foldable := make([]utils.Point, 0)
switch f.Orientation {
case 'x':
for pt := range pts {
if pt.X > f.Position {
foldable = append(foldable, pt)
}
}
for _, pt := range foldable {
delete(pts, pt)
pt.X = 2*f.Position - pt.X
pts[pt] = true
}
case 'y':
for pt := range pts {
if pt.Y > f.Position {
foldable = append(foldable, pt)
}
}
for _, pt := range foldable {
delete(pts, pt)
pt.Y = 2*f.Position - pt.Y
pts[pt] = true
}
}
}
func parseSheet(lines []string) (map[utils.Point]bool, []Fold) {
pts := make(map[utils.Point]bool)
folds := make([]Fold, 0)
for _, ln := range lines {
switch {
case len(ln) == 0:
// Skip blank lines
case strings.HasPrefix(ln, "fold"):
// Fold instruction
var fold Fold
_, err := fmt.Sscanf(ln, "fold along %c=%d", &fold.Orientation, &fold.Position)
utils.Check(err, "Unable to parse fold statement")
folds = append(folds, fold)
default:
// Point
var pt utils.Point
_, err := fmt.Sscanf(ln, "%d,%d", &pt.X, &pt.Y)
utils.Check(err, "unable to parse point")
pts[pt] = true
}
}
return pts, folds
}