Skip to content

Commit 5c73886

Browse files
authored
feat: Implement 2016/day02 (#41)
* feat: Initial commit for 2016/day02 * feat: Implement 2016/day02 part1 * feat: Implement 2016/day02 part 2 * docs: Mark 2016/day02 as done * fix: Fix linter warnings * refactor: dry * refactor: Move comments to func line comment * refactor * refactor: Simplify solution * chore: Update Makefile comments
1 parent 85b7b10 commit 5c73886

File tree

10 files changed

+426
-29
lines changed

10 files changed

+426
-29
lines changed

.deepsource.toml

Lines changed: 0 additions & 22 deletions
This file was deleted.

Makefile

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ help:
2626

2727

2828

29+
## Build project.
2930
build: compile-aoc-cli
3031
.PHONY: build
3132

33+
## Compile aoc-cli.
3234
compile-aoc-cli:
3335
./scripts/build/aoc-cli.sh
3436
.PHONY: compile-spamassassin-parser-be
@@ -48,24 +50,26 @@ open-cover-report: test-cover
4850
./scripts/open-coverage-report.sh
4951
.PHONY: open-cover-report
5052

53+
## Update readme coverage.
5154
update-readme-cover: build test-cover
5255
./scripts/update-readme-coverage.sh
5356
.PHONY: update-readme-cover
5457

58+
## Run tests.
5559
test:
5660
./scripts/tests/run.sh
5761
.PHONY: test
5862

63+
## Sync vendor and install needed tools.
64+
configure: sync-vendor install-tools
5965

60-
configure: sync-vendor
61-
66+
## Sync vendor with go.mod.
6267
sync-vendor:
6368
./scripts/sync-vendor.sh
6469
.PHONY: sync-vendor
6570

6671
## Fix imports sorting.
6772
imports:
68-
${call colored, fix-imports is running...}
6973
./scripts/style/fix-imports.sh
7074
.PHONY: imports
7175

@@ -78,6 +82,7 @@ fmt:
7882
format-project: fmt imports
7983
.PHONY: format-project
8084

85+
## Installs vendored tools.
8186
install-tools:
8287
./scripts/install/vendored-tools.sh
8388
.PHONY: install-tools
@@ -131,6 +136,7 @@ new-version: vet test build
131136
./scripts/release/new-version.sh
132137
.PHONY: new-release
133138

139+
## Open advent of code homepage in browser.
134140
open-advent-homepage:
135141
./scripts/browser-opener.sh -u 'https://adventofcode.com/'
136142

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ This repository contains solutions for puzzles and cli tool to run solutions to
6363
<summary>2016</summary>
6464

6565
- [x] [Day 1: No Time for a Taxicab](https://adventofcode.com/2016/day/1)
66-
- [ ] [Day 2: Bathroom Security](https://adventofcode.com/2016/day/2)
66+
- [x] [Day 2: Bathroom Security](https://adventofcode.com/2016/day/2)
6767
- [ ] [Day 3: Squares With Three Sides](https://adventofcode.com/2016/day/3)
6868
- [ ] [Day 4: Security Through Obscurity](https://adventofcode.com/2016/day/4)
6969
- [ ] [Day 5: How About a Nice Game of Chess?](https://adventofcode.com/2016/day/5)

cmd/aoc-cli/main_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,10 +473,10 @@ func testcases2016() []testcase {
473473
want: puzzles.Result{
474474
Year: year,
475475
Name: puzzles.Day02.String(),
476-
Part1: "",
477-
Part2: "",
476+
Part1: "48584",
477+
Part2: "563B6",
478478
},
479-
wantErr: true,
479+
wantErr: false,
480480
},
481481
{
482482
name: "2016/day03",
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
RRLUDDLDUDUDUDRDDDRDDRLUUUDRUDURURURLRDDULLLDRRRRULDDRDDURDLURLURRUULRURDDDDLDDRRLDUDUUDURURDLDRRURDLLLDLLRUDRLDDRUULLLLLRRLDUDLUUDRUULLRLLLRLUURDLDLLDDRULDLUURRURLUUURLLDDULRDULULRULDDLRDDUUDLRRURLLURURLDDLURRLUURRRRLDRDLDUDRUDDRULLDUDDLRRLUUUUUDDLLDRLURDDRLLUDULDRDDLLUURUUUURDRLRLLULUULULLRRDLULRUDURDLRLRDDDRULLUULRURULLLUDUURUUUURUULDURDRRRULRLULDLRRULULUUDDDRDURLLURLLDUUUUDULRDLRDUUDDLDUDRLLRLRRRLULUDDDURLRRURUDDDRDRDRLLRDRDLDDRRDRDLLRLLLRRULRDDURRDUDRURDLDULLRRLURLRLLDURRRLLDRRURRRUULDRLDUULRDLDLURUDLLDLLUUDDDUUUDRL
2+
DLRRDRRDDRRDURLUDDDDDULDDLLDRLURDDDDDDRDDDRDDDLLRRULLLRUDULLDURULRRDLURURUDRUURDRLUURRUDRUULUURULULDDLLDDRLDUDDRDRDDUULDULDDLUDUDDUDLULLUDLLLLLRRRUURLUUUULRURULUDDULLLRLRDRUUULULRUUUULRDLLDLDRDRDRDRRUUURULDUUDLDRDRURRUDDRLDULDDRULRRRLRDDUUDRUDLDULDURRDUDDLULULLDULLLRRRDULLLRRURDUURULDRDURRURRRRDLDRRUDDLLLDRDRDRURLUURURRUUURRUDLDDULDRDRRURDLUULDDUUUURLRUULRUURLUUUDLUDRLURUDLDLDLURUURLDURDDDDRURULLULLDRDLLRRLDLRRRDURDULLLDLRLDR
3+
URURLLDRDLULULRDRRDDUUUDDRDUURULLULDRLUDLRUDDDLDRRLURLURUUDRLDUULDRDURRLLUDLDURRRRLURLDDRULRLDULDDRRLURDDRLUDDULUDULRLDULDLDUDRLLDDRRRDULLDLRRLDRLURLUULDDDDURULLDLLLDRRLRRLLRDDRDLDRURRUURLLDDDLRRRRRDLRRDRLDDDLULULRLUURULURUUDRULRLLRDLDULDRLLLDLRRRUDURLUURRUDURLDDDRDRURURRLRRLDDRURULDRUURRLULDLUDUULDLUULUDURRDDRLLLRLRRLUUURRDRUULLLRUUURLLDDRDRULDULURRDRURLRRLRDURRURRDLDUDRURUULULDDUDUULDRDURRRDLURRLRLDUDRDULLURLRRUDLUDRRRULRURDUDDDURLRULRRUDUUDDLLLURLLRLLDRDUURDDLUDLURDRRDLLRLURRUURRLDUUUUDUD
4+
DRRDRRRLDDLDUDRDLRUUDRDUDRRDUDRDURRDDRLLURUUDRLRDDULLUULRUUDDRLDLRULDLRLDUDULUULLLRDLURDRDURURDUDUDDDRRLRRLLRULLLLRDRDLRRDDDLULDLLUUULRDURRULDDUDDDURRDRDRDRULRRRDRUDLLDDDRULRRLUDRDLDLDDDLRLRLRLDULRLLRLRDUUULLRRDLLRDULURRLDUDDULDDRLUDLULLRLDUDLULRDURLRULLRRDRDDLUULUUUULDRLLDRDLUDURRLLDURLLDDLLUULLDURULULDLUUDLRURRRULUDRLDRDURLDUDDULRDRRDDRLRRDDRUDRURULDRRLUURUDULDDDLRRRRDRRRLLURUURLRLULUULLRLRDLRRLLUULLDURDLULURDLRUUDUUURURUURDDRLULUUULRDRDRUUDDDRDRL
5+
RLRUDDUUDDDDRRLRUUDLLDRUUUDRRDLDRLRLLDRLUDDURDLDUDRRUURULLRRLUULLUDRDRUDDULRLLUDLULRLRRUUDLDLRDDDRDDDUDLULDLRRLUDUDDRRRRDRDRUUDDURLRDLLDLDLRRDURULDRLRRURULRDDLLLRULLRUUUDLDUURDUUDDRRRDDRLDDRULRRRDRRLUDDDRUURRDRRDURDRUDRRDLUDDURRLUDUDLLRUURLRLLLDDURUDLDRLRLLDLLULLDRULUURLDDULDDRDDDURULLDRDDLURRDDRRRLDLRLRRLLDLLLRDUDDULRLUDDUULUDLDDDULULDLRDDLDLLLDUUDLRRLRDRRUUUURLDLRRLDULURLDRDURDDRURLDLDULURRRLRUDLDURDLLUDULDDU

internal/puzzles/solutions/2015/day02/solution.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ func part1(input io.Reader) (string, error) {
5050
res += b.surfaceWithExtra()
5151
}
5252

53+
if err := scanner.Err(); err != nil {
54+
return "", fmt.Errorf("scanner error: %w", err)
55+
}
56+
5357
return strconv.Itoa(res), nil
5458
}
5559

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
// Package day02 contains solution for https://adventofcode.com/2016/day/2 puzzle.
2+
package day02
3+
4+
import (
5+
"bufio"
6+
"errors"
7+
"fmt"
8+
"io"
9+
"strings"
10+
11+
"github.com/obalunenko/advent-of-code/internal/puzzles"
12+
)
13+
14+
func init() {
15+
puzzles.Register(solution{})
16+
}
17+
18+
type solution struct{}
19+
20+
func (s solution) Day() string {
21+
return puzzles.Day02.String()
22+
}
23+
24+
func (s solution) Year() string {
25+
return puzzles.Year2016.String()
26+
}
27+
28+
func (s solution) Part1(input io.Reader) (string, error) {
29+
return part1(input)
30+
}
31+
32+
func (s solution) Part2(input io.Reader) (string, error) {
33+
return part2(input)
34+
}
35+
36+
func part2(input io.Reader) (string, error) {
37+
kpd := loadKeypadPart2()
38+
39+
return getPassword(kpd, input)
40+
}
41+
42+
func part1(input io.Reader) (string, error) {
43+
kpd := loadKeypadPart1()
44+
45+
return getPassword(kpd, input)
46+
}
47+
48+
func getPassword(kpd keypad, input io.Reader) (string, error) {
49+
reader := bufio.NewReader(input)
50+
51+
var pwd strings.Builder
52+
53+
for {
54+
r, _, err := reader.ReadRune()
55+
if err != nil {
56+
if errors.Is(err, io.EOF) {
57+
break
58+
}
59+
60+
return "", fmt.Errorf("read rune: %w", err)
61+
}
62+
63+
m := string(r)
64+
65+
if r == '\n' {
66+
cur := kpd.numb()
67+
68+
_, err = pwd.WriteString(cur)
69+
if err != nil {
70+
return "", fmt.Errorf("write string: %w", err)
71+
}
72+
73+
continue
74+
}
75+
76+
if err = kpd.move(move(m)); err != nil {
77+
return "", fmt.Errorf("move: %w", err)
78+
}
79+
}
80+
81+
return pwd.String(), nil
82+
}
83+
84+
type move string
85+
86+
const (
87+
up = move("U")
88+
down = move("D")
89+
left = move("L")
90+
right = move("R")
91+
)
92+
93+
type keypadPos struct {
94+
x int
95+
y int
96+
}
97+
98+
type grid [][]string
99+
100+
type keypad struct {
101+
finger keypadPos
102+
grid grid
103+
}
104+
105+
/*
106+
loadKeypadPart2
107+
keyboard
108+
109+
1
110+
2 3 4
111+
5 6 7 8 9
112+
A B C
113+
D
114+
115+
start at `5`
116+
117+
let's predict that this is a 2 dimension matrix and '5' is 0,2m
118+
*/
119+
func loadKeypadPart2() keypad {
120+
start := keypadPos{
121+
x: 0,
122+
y: 2,
123+
}
124+
125+
g := [][]string{
126+
{"", "", "1", "", ""},
127+
{"", "2", "3", "4", ""},
128+
{"5", "6", "7", "8", "9"},
129+
{"", "A", "B", "C", ""},
130+
{"", "", "D", "", ""},
131+
}
132+
133+
return keypad{
134+
finger: start,
135+
grid: g,
136+
}
137+
}
138+
139+
/*
140+
loadKeypadPart1
141+
keyboard
142+
1 2 3
143+
4 5 6
144+
7 8 9
145+
146+
let's predict that this is a 2 dimension matrix and 5 is a 1,1
147+
*/
148+
func loadKeypadPart1() keypad {
149+
g := [][]string{
150+
{"1", "2", "3"},
151+
{"4", "5", "6"},
152+
{"7", "8", "9"},
153+
}
154+
155+
start := keypadPos{
156+
x: 1,
157+
y: 1,
158+
}
159+
160+
return newKeypad(g, start)
161+
}
162+
163+
func newKeypad(specs grid, startPos keypadPos) keypad {
164+
return keypad{
165+
finger: startPos,
166+
grid: specs,
167+
}
168+
}
169+
170+
func (k *keypad) move(m move) error {
171+
switch m {
172+
case up:
173+
if k.canMoveUp() {
174+
k.finger.y--
175+
}
176+
177+
case down:
178+
if k.canMoveDown() {
179+
k.finger.y++
180+
}
181+
182+
case left:
183+
if k.canMoveLeft() {
184+
k.finger.x--
185+
}
186+
case right:
187+
if k.canMoveRight() {
188+
k.finger.x++
189+
}
190+
default:
191+
return fmt.Errorf("unsupported move")
192+
}
193+
194+
return nil
195+
}
196+
197+
func (k keypad) canMoveRight() bool {
198+
cur := k.finger
199+
200+
if cur.x == len(k.grid[cur.y])-1 {
201+
return false
202+
}
203+
204+
return k.grid[cur.y][cur.x+1] != ""
205+
}
206+
207+
func (k keypad) canMoveLeft() bool {
208+
cur := k.finger
209+
210+
if cur.x == 0 {
211+
return false
212+
}
213+
214+
return k.grid[cur.y][cur.x-1] != ""
215+
}
216+
217+
func (k keypad) canMoveUp() bool {
218+
cur := k.finger
219+
220+
if cur.y == 0 {
221+
return false
222+
}
223+
224+
return k.grid[cur.y-1][cur.x] != ""
225+
}
226+
227+
func (k keypad) canMoveDown() bool {
228+
cur := k.finger
229+
230+
if cur.y == len(k.grid)-1 {
231+
return false
232+
}
233+
234+
return k.grid[cur.y+1][cur.x] != ""
235+
}
236+
237+
func (k keypad) numb() string {
238+
return k.grid[k.finger.y][k.finger.x]
239+
}

0 commit comments

Comments
 (0)