Day 10: Part 1 and 2

Signed-off-by: James Griffin <james@unsupervised.ca>
This commit is contained in:
2020-12-10 22:27:04 -04:00
parent 1cb55213bc
commit 9bf150623e
6 changed files with 346 additions and 3 deletions

10
main.go
View File

@@ -3,7 +3,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/thatguygriff/aoc2020/nine" "github.com/thatguygriff/aoc2020/ten"
) )
func main() { func main() {
@@ -40,6 +40,10 @@ func main() {
// fmt.Println(eight.PartTwo()) // fmt.Println(eight.PartTwo())
// Day 9 // Day 9
fmt.Println(nine.PartOne()) // fmt.Println(nine.PartOne())
fmt.Println(nine.PartTwo()) // fmt.Println(nine.PartTwo())
// Day 10
fmt.Println(ten.PartOne())
fmt.Println(ten.PartTwo())
} }

119
ten/day_ten.go Normal file
View File

@@ -0,0 +1,119 @@
package ten
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
)
func newBag(f string) *bag {
b := &bag{}
b.load(f)
return b
}
type adapter struct {
output int
}
type bag struct {
adapters []adapter
}
func (b *bag) load(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
v, err := strconv.Atoi(scanner.Text())
if err != nil {
return err
}
b.adapters = append(b.adapters, adapter{
output: v,
})
}
return nil
}
func (b *bag) distribution() (one, two, three int, err error) {
if len(b.adapters) == 0 {
return one, two, three, nil
}
sort.SliceStable(b.adapters, func(i, j int) bool { return b.adapters[i].output < b.adapters[j].output })
current := 0
for i := 0; i < len(b.adapters); i++ {
next := b.adapters[i].output
switch next - current {
case 1:
one++
case 2:
two++
case 3:
three++
default:
return one, two, three, fmt.Errorf("Unsupported joltage difference %d", b.adapters[i+1].output-b.adapters[i].output)
}
current = next
}
// The device is always 3 higher
three++
return one, two, three, nil
}
func (b *bag) countArrangements() int {
if len(b.adapters) == 0 {
return 0
}
sort.SliceStable(b.adapters, func(i, j int) bool { return b.adapters[i].output < b.adapters[j].output })
// Pilfered from reddit after beating my head against a wall not getting the looping correct
outputs := []int{0}
for _, a := range b.adapters {
outputs = append(outputs, a.output)
}
outputs = append(outputs, outputs[len(outputs)-1]+3)
dp := make([]int, len(outputs))
dp[0] = 1
dp[1] = 1
for i := 2; i < len(dp); i++ {
for j := i - 1; j >= 0; j-- {
if outputs[i]-outputs[j] <= 3 {
dp[i] += dp[j]
} else {
break
}
}
}
return dp[len(dp)-1]
}
// PartOne Find the jolt difference product
func PartOne() string {
b := newBag("ten/input.txt")
one, two, three, err := b.distribution()
if err != nil {
return fmt.Sprintf("Unable to find a distribution: %v", err)
}
return fmt.Sprintf("Got %d, %d, %d jolts differences with a %d product", one, two, three, one*three)
}
// PartTwo Find the number of arrangements of adapters
func PartTwo() string {
b := newBag("ten/input.txt")
return fmt.Sprintf("Found %d possible arrangements", b.countArrangements())
}

71
ten/day_ten_test.go Normal file
View File

@@ -0,0 +1,71 @@
package ten
import "testing"
func Test_program_load(t *testing.T) {
b := bag{}
err := b.load("sample1.txt")
if err != nil {
t.Log(err)
t.FailNow()
}
if len(b.adapters) != 11 {
t.Logf("Expected 11 adapters, Got %d adapters", len(b.adapters))
t.FailNow()
}
}
func Test_distribution_sample1(t *testing.T) {
b := bag{}
b.load("sample1.txt")
one, two, three, err := b.distribution()
if err != nil {
t.Logf(err.Error())
t.FailNow()
}
if one != 7 || two != 0 || three != 5 {
t.Logf("Expected 7, 0, 5 jolt diffs, Got %d, %d, %d jolts", one, two, three)
t.FailNow()
}
}
func Test_distribution_sample2(t *testing.T) {
b := bag{}
b.load("sample2.txt")
one, two, three, err := b.distribution()
if err != nil {
t.Logf(err.Error())
t.FailNow()
}
if one != 22 || two != 0 || three != 10 {
t.Logf("Expected 22, 0, 10 jolt diffs, Got %d, %d, %d jolts", one, two, three)
t.FailNow()
}
}
func Test_arrangement_sample1(t * testing.T) {
b := newBag("sample1.txt")
count := b.countArrangements()
if count != 8 {
t.Logf("Expected 8 arrangments, got %d", count)
t.FailNow()
}
}
func Test_arrangement_sample2(t * testing.T) {
b := newBag("sample2.txt")
count := b.countArrangements()
if count != 19208 {
t.Logf("Expected 19208 arrangments, got %d", count)
t.FailNow()
}
}

107
ten/input.txt Normal file
View File

@@ -0,0 +1,107 @@
48
171
156
51
26
6
80
62
65
82
130
97
49
31
142
83
75
20
154
119
56
114
92
33
140
74
118
1
96
44
128
134
121
64
158
27
17
101
59
12
89
88
145
167
11
3
39
43
105
16
170
63
111
2
108
21
146
77
45
52
32
127
147
76
58
37
86
129
57
133
120
163
138
161
139
71
9
141
168
164
124
157
95
25
38
69
87
155
135
15
102
70
34
42
24
50
68
169
10
55
117
30
81
151
100
162
148

11
ten/sample1.txt Normal file
View File

@@ -0,0 +1,11 @@
16
10
15
5
1
11
7
19
6
12
4

31
ten/sample2.txt Normal file
View File

@@ -0,0 +1,31 @@
28
33
18
42
31
14
46
20
48
47
24
23
49
45
19
38
39
11
1
32
25
35
8
17
7
9
4
2
34
10
3