-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday05.go
117 lines (106 loc) · 2.24 KB
/
day05.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
package main
import (
"bufio"
"fmt"
"io"
"log"
"os"
"regexp"
"strconv"
)
func readLines(r io.Reader) ([]string, error) {
lines := make([]string, 0)
scanner := bufio.NewScanner(r)
for scanner.Scan() {
if err := scanner.Err(); err != nil {
return nil, err
}
lines = append(lines, scanner.Text())
}
return lines, nil
}
func toInts(strs []string) ([]int, error) {
ints := make([]int, len(strs))
for idx, s := range strs {
i, err := strconv.Atoi(s)
if err != nil {
return nil, err
}
ints[idx] = i
}
return ints, nil
}
func pos(lines []string, sep string) int {
for i, line := range lines {
if line == sep {
return i
}
}
return -1
}
func parseStacks(lines []string) [][]byte {
// Determine shape
h := len(lines)
w := (len(lines[0]) + 1) / 4
results := make([][]byte, 0, w)
for x := 0; x < w; x++ {
px := 1 + 4*x
stack := make([]byte, 0, h-1)
for y := h - 2; y >= 0; y-- {
c := lines[y][px]
if c != ' ' {
stack = append(stack, c)
}
}
results = append(results, stack)
}
return results
}
func move1(stacks [][]byte, num int, from int, to int) {
for i := 0; i < num; i++ {
p := len(stacks[from]) - 1
x := stacks[from][p]
stacks[from] = stacks[from][:p]
stacks[to] = append(stacks[to], x)
}
}
func move2(stacks [][]byte, num int, from int, to int) {
s := len(stacks[from]) - num
take := stacks[from][s:]
stacks[from] = stacks[from][:s]
stacks[to] = append(stacks[to], take...)
}
func tops(stacks [][]byte) string {
tops := make([]byte, len(stacks))
for i, stack := range stacks {
tops[i] = stack[len(stack)-1]
}
return string(tops)
}
func run() error {
lines, err := readLines(os.Stdin)
if err != nil {
return err
}
sep := pos(lines, "")
stacks1 := parseStacks(lines[:sep])
stacks2 := parseStacks(lines[:sep])
re := regexp.MustCompile(`^move (\d+) from (\d+) to (\d+)$`)
for _, command := range lines[sep+1:] {
m := re.FindStringSubmatch(command)
pos, err := toInts(m[1:])
if err != nil {
return err
}
move1(stacks1, pos[0], pos[1]-1, pos[2]-1)
move2(stacks2, pos[0], pos[1]-1, pos[2]-1)
}
fmt.Printf("Part1: %s\n", tops(stacks1))
fmt.Printf("Part2: %s\n", tops(stacks2))
return nil
}
func main() {
if err := run(); err != nil {
log.Fatalf("run(): %v", err)
}
}