Skip to content

Commit 68ef972

Browse files
days 16, 17, and 18
1 parent fdefad5 commit 68ef972

File tree

12 files changed

+1173
-3
lines changed

12 files changed

+1173
-3
lines changed

β€Žday16/day16.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package day16
2+
3+
import (
4+
"regexp"
5+
"strings"
6+
7+
"github.com/alokmenghrajani/adventofcode2020/utils"
8+
)
9+
10+
type rule struct {
11+
name string
12+
min1, max1, min2, max2 int
13+
offsets map[int]bool
14+
final int
15+
}
16+
17+
func Part1(input string) int {
18+
var rules []rule
19+
20+
parts := strings.Split(input, "\n\n")
21+
for _, line := range strings.Split(parts[0], "\n") {
22+
re := regexp.MustCompile(`^(.*?): (\d+)-(\d+) or (\d+)-(\d+)`)
23+
match := re.FindStringSubmatch(line)
24+
r := rule{
25+
name: match[1],
26+
min1: utils.MustAtoi(match[2]),
27+
max1: utils.MustAtoi(match[3]),
28+
min2: utils.MustAtoi(match[4]),
29+
max2: utils.MustAtoi(match[5]),
30+
offsets: map[int]bool{},
31+
}
32+
rules = append(rules, r)
33+
}
34+
35+
res := 0
36+
t := strings.Split(parts[2], "\n")
37+
for _, line := range t[1:] {
38+
for _, n := range strings.Split(line, ",") {
39+
n2 := utils.MustAtoi(n)
40+
ok := false
41+
for _, r := range rules {
42+
if (n2 >= r.min1 && n2 <= r.max1) || (n2 >= r.min2 && n2 <= r.max2) {
43+
ok = true
44+
break
45+
}
46+
}
47+
if !ok {
48+
res += n2
49+
}
50+
}
51+
}
52+
return res
53+
}
54+
55+
func Part2(input string) int {
56+
var rules []rule
57+
58+
parts := strings.Split(input, "\n\n")
59+
for _, line := range strings.Split(parts[0], "\n") {
60+
re := regexp.MustCompile(`^(.*?): (\d+)-(\d+) or (\d+)-(\d+)`)
61+
match := re.FindStringSubmatch(line)
62+
r := rule{
63+
name: match[1],
64+
min1: utils.MustAtoi(match[2]),
65+
max1: utils.MustAtoi(match[3]),
66+
min2: utils.MustAtoi(match[4]),
67+
max2: utils.MustAtoi(match[5]),
68+
offsets: map[int]bool{},
69+
}
70+
rules = append(rules, r)
71+
}
72+
73+
t := strings.Split(parts[2], "\n")
74+
for _, line := range t[1:] {
75+
for offset, n := range strings.Split(line, ",") {
76+
n2 := utils.MustAtoi(n)
77+
ok := false
78+
for _, r := range rules {
79+
if (n2 >= r.min1 && n2 <= r.max1) || (n2 >= r.min2 && n2 <= r.max2) {
80+
ok = true
81+
break
82+
}
83+
}
84+
if ok {
85+
for rnumber, r := range rules {
86+
if (n2 >= r.min1 && n2 <= r.max1) || (n2 >= r.min2 && n2 <= r.max2) {
87+
_, tok := rules[rnumber].offsets[offset]
88+
if !tok {
89+
rules[rnumber].offsets[offset] = true
90+
}
91+
} else {
92+
rules[rnumber].offsets[offset] = false
93+
}
94+
}
95+
96+
}
97+
}
98+
}
99+
100+
// clean
101+
for i, _ := range rules {
102+
for k, v := range rules[i].offsets {
103+
if !v {
104+
delete(rules[i].offsets, k)
105+
}
106+
}
107+
}
108+
109+
// find positions
110+
done := false
111+
for !done {
112+
done = true
113+
for i, _ := range rules {
114+
if len(rules[i].offsets) == 1 {
115+
var k int
116+
for k, _ = range rules[i].offsets {
117+
break
118+
}
119+
rules[i].final = k
120+
done = false
121+
for j, _ := range rules {
122+
delete(rules[j].offsets, k)
123+
}
124+
}
125+
}
126+
}
127+
128+
tickets := strings.Split(parts[1], "\n")
129+
ticket := strings.Split(tickets[1], ",")
130+
res := 1
131+
for _, r := range rules {
132+
if strings.HasPrefix(r.name, "departure") {
133+
res = res * utils.MustAtoi(ticket[r.final])
134+
}
135+
}
136+
137+
return res
138+
}

β€Žday16/day16_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package day16
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestPart1(t *testing.T) {
10+
r := Part1(`class: 1-3 or 5-7
11+
row: 6-11 or 33-44
12+
seat: 13-40 or 45-50
13+
14+
your ticket:
15+
7,1,14
16+
17+
nearby tickets:
18+
7,3,47
19+
40,4,50
20+
55,2,20
21+
38,6,12`)
22+
require.Equal(t, 71, r)
23+
}

β€Žday16/input.txt

Lines changed: 264 additions & 0 deletions
Large diffs are not rendered by default.

β€Žday17/day17.go

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
package day17
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/alokmenghrajani/adventofcode2020/utils"
8+
)
9+
10+
var minX, maxX, minY, maxY, minZ, maxZ int
11+
var minZZ, maxZZ int
12+
13+
func Part1(input string) int {
14+
g := map[string]bool{}
15+
for y, line := range strings.Split(input, "\n") {
16+
for x, c := range line {
17+
if c == '#' {
18+
g[makeKey(x, y, 0)] = true
19+
minX = utils.IntMin(minX, x)
20+
maxX = utils.IntMax(maxX, x)
21+
minY = utils.IntMin(minY, y)
22+
maxY = utils.IntMax(maxY, y)
23+
}
24+
}
25+
}
26+
27+
for i := 0; i < 6; i++ {
28+
g = compute(g)
29+
}
30+
31+
return len(g)
32+
}
33+
34+
func makeKey(x, y, z int) string {
35+
return fmt.Sprintf("%d:%d:%d", x, y, z)
36+
}
37+
38+
func compute(g map[string]bool) map[string]bool {
39+
rmap := map[string]bool{}
40+
41+
cMinX := minX
42+
cMaxX := maxX
43+
cMinY := minY
44+
cMaxY := maxY
45+
cMinZ := minZ
46+
cMaxZ := maxZ
47+
48+
for x := cMinX - 1; x <= cMaxX+1; x++ {
49+
for y := cMinY - 1; y <= cMaxY+1; y++ {
50+
for z := cMinZ - 1; z <= cMaxZ+1; z++ {
51+
// count neighbors
52+
r := 0
53+
for i := -1; i <= 1; i++ {
54+
for j := -1; j <= 1; j++ {
55+
for k := -1; k <= 1; k++ {
56+
if i == 0 && j == 0 && k == 0 {
57+
continue
58+
}
59+
if g[makeKey(x+i, y+j, z+k)] {
60+
r++
61+
}
62+
}
63+
}
64+
}
65+
66+
if g[makeKey(x, y, z)] {
67+
if r == 2 || r == 3 {
68+
rmap[makeKey(x, y, z)] = true
69+
minX = utils.IntMin(minX, x)
70+
maxX = utils.IntMax(maxX, x)
71+
minY = utils.IntMin(minY, y)
72+
maxY = utils.IntMax(maxY, y)
73+
minZ = utils.IntMin(minZ, z)
74+
maxZ = utils.IntMax(maxZ, z)
75+
}
76+
} else {
77+
if r == 3 {
78+
rmap[makeKey(x, y, z)] = true
79+
minX = utils.IntMin(minX, x)
80+
maxX = utils.IntMax(maxX, x)
81+
minY = utils.IntMin(minY, y)
82+
maxY = utils.IntMax(maxY, y)
83+
minZ = utils.IntMin(minZ, z)
84+
maxZ = utils.IntMax(maxZ, z)
85+
}
86+
}
87+
}
88+
}
89+
}
90+
91+
return rmap
92+
}
93+
94+
func Part2(input string) int {
95+
g := map[string]bool{}
96+
for y, line := range strings.Split(input, "\n") {
97+
for x, c := range line {
98+
if c == '#' {
99+
g[makeKey2(x, y, 0, 0)] = true
100+
minX = utils.IntMin(minX, x)
101+
maxX = utils.IntMax(maxX, x)
102+
minY = utils.IntMin(minY, y)
103+
maxY = utils.IntMax(maxY, y)
104+
}
105+
}
106+
}
107+
108+
for i := 0; i < 6; i++ {
109+
g = compute2(g)
110+
}
111+
112+
return len(g)
113+
}
114+
115+
func compute2(g map[string]bool) map[string]bool {
116+
rmap := map[string]bool{}
117+
118+
cMinX := minX
119+
cMaxX := maxX
120+
cMinY := minY
121+
cMaxY := maxY
122+
cMinZ := minZ
123+
cMaxZ := maxZ
124+
cMinZZ := minZZ
125+
cMaxZZ := maxZZ
126+
127+
for x := cMinX - 1; x <= cMaxX+1; x++ {
128+
for y := cMinY - 1; y <= cMaxY+1; y++ {
129+
for z := cMinZ - 1; z <= cMaxZ+1; z++ {
130+
for zz := cMinZZ - 1; zz <= cMaxZZ+1; zz++ {
131+
// count neighbors
132+
r := 0
133+
for i := -1; i <= 1; i++ {
134+
for j := -1; j <= 1; j++ {
135+
for k := -1; k <= 1; k++ {
136+
for kk := -1; kk <= 1; kk++ {
137+
if i == 0 && j == 0 && k == 0 && kk == 0 {
138+
continue
139+
}
140+
if g[makeKey2(x+i, y+j, z+k, zz+kk)] {
141+
r++
142+
}
143+
}
144+
}
145+
}
146+
}
147+
148+
if g[makeKey2(x, y, z, zz)] {
149+
if r == 2 || r == 3 {
150+
rmap[makeKey2(x, y, z, zz)] = true
151+
minX = utils.IntMin(minX, x)
152+
maxX = utils.IntMax(maxX, x)
153+
minY = utils.IntMin(minY, y)
154+
maxY = utils.IntMax(maxY, y)
155+
minZ = utils.IntMin(minZ, z)
156+
maxZ = utils.IntMax(maxZ, z)
157+
minZZ = utils.IntMin(minZZ, zz)
158+
maxZZ = utils.IntMax(maxZZ, zz)
159+
}
160+
} else {
161+
if r == 3 {
162+
rmap[makeKey2(x, y, z, zz)] = true
163+
minX = utils.IntMin(minX, x)
164+
maxX = utils.IntMax(maxX, x)
165+
minY = utils.IntMin(minY, y)
166+
maxY = utils.IntMax(maxY, y)
167+
minZ = utils.IntMin(minZ, z)
168+
maxZ = utils.IntMax(maxZ, z)
169+
minZZ = utils.IntMin(minZZ, zz)
170+
maxZZ = utils.IntMax(maxZZ, zz)
171+
}
172+
}
173+
}
174+
}
175+
}
176+
}
177+
178+
return rmap
179+
}
180+
181+
func makeKey2(x, y, z, zz int) string {
182+
return fmt.Sprintf("%d:%d:%d:%d", x, y, z, zz)
183+
}

β€Žday17/day17_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package day17
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestPart1(t *testing.T) {
10+
r := Part1(`.#.
11+
..#
12+
###`)
13+
require.Equal(t, 112, r)
14+
}
15+
16+
func TestPart2(t *testing.T) {
17+
r := Part2(`.#.
18+
..#
19+
###`)
20+
require.Equal(t, 848, r)
21+
}

β€Žday17/input.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
###..#..
2+
.#######
3+
#####...
4+
#..##.#.
5+
###..##.
6+
##...#..
7+
..#...#.
8+
.#....##

0 commit comments

Comments
Β (0)