diff --git a/main.go b/main.go index 3d05643..1ec5a59 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,7 @@ package main import ( "fmt" - "github.com/thatguygriff/aoc2020/nine" + "github.com/thatguygriff/aoc2020/ten" ) func main() { @@ -40,6 +40,10 @@ func main() { // fmt.Println(eight.PartTwo()) // Day 9 - fmt.Println(nine.PartOne()) - fmt.Println(nine.PartTwo()) + // fmt.Println(nine.PartOne()) + // fmt.Println(nine.PartTwo()) + + // Day 10 + fmt.Println(ten.PartOne()) + fmt.Println(ten.PartTwo()) } diff --git a/ten/day_ten.go b/ten/day_ten.go new file mode 100644 index 0000000..360cddc --- /dev/null +++ b/ten/day_ten.go @@ -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()) +} diff --git a/ten/day_ten_test.go b/ten/day_ten_test.go new file mode 100644 index 0000000..026814d --- /dev/null +++ b/ten/day_ten_test.go @@ -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() + } +} \ No newline at end of file diff --git a/ten/input.txt b/ten/input.txt new file mode 100644 index 0000000..fede17e --- /dev/null +++ b/ten/input.txt @@ -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 \ No newline at end of file diff --git a/ten/sample1.txt b/ten/sample1.txt new file mode 100644 index 0000000..cd1b40b --- /dev/null +++ b/ten/sample1.txt @@ -0,0 +1,11 @@ +16 +10 +15 +5 +1 +11 +7 +19 +6 +12 +4 \ No newline at end of file diff --git a/ten/sample2.txt b/ten/sample2.txt new file mode 100644 index 0000000..be5c492 --- /dev/null +++ b/ten/sample2.txt @@ -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 \ No newline at end of file