From 67632d0020e812be497b1acde1c8cd5fade840f9 Mon Sep 17 00:00:00 2001 From: Oleg Balunenko Date: Tue, 21 Dec 2021 00:13:42 +0300 Subject: [PATCH 1/2] feat(puzzles): Add specs and tests for 2021/day08 puzzle --- .../puzzles/solutions/2021/day08/solution.go | 30 +++++ .../solutions/2021/day08/solution_test.go | 117 ++++++++++++++++++ internal/puzzles/solutions/2021/day08/spec.md | 90 ++++++++++++++ .../solutions/2021/day08/testdata/input.txt | 10 ++ 4 files changed, 247 insertions(+) create mode 100644 internal/puzzles/solutions/2021/day08/solution.go create mode 100644 internal/puzzles/solutions/2021/day08/solution_test.go create mode 100644 internal/puzzles/solutions/2021/day08/spec.md create mode 100644 internal/puzzles/solutions/2021/day08/testdata/input.txt diff --git a/internal/puzzles/solutions/2021/day08/solution.go b/internal/puzzles/solutions/2021/day08/solution.go new file mode 100644 index 00000000..4cb99345 --- /dev/null +++ b/internal/puzzles/solutions/2021/day08/solution.go @@ -0,0 +1,30 @@ +// Package day08 contains solution for https://adventofcode.com/2021/day/8 puzzle. +package day08 + +import ( + "io" + + "github.com/obalunenko/advent-of-code/internal/puzzles" +) + +func init() { + puzzles.Register(solution{}) +} + +type solution struct{} + +func (solution) Day() string { + return puzzles.Day08.String() +} + +func (solution) Year() string { + return puzzles.Year2021.String() +} + +func (solution) Part1(input io.Reader) (string, error) { + return "", puzzles.ErrNotImplemented +} + +func (solution) Part2(input io.Reader) (string, error) { + return "", puzzles.ErrNotImplemented +} diff --git a/internal/puzzles/solutions/2021/day08/solution_test.go b/internal/puzzles/solutions/2021/day08/solution_test.go new file mode 100644 index 00000000..bcf03648 --- /dev/null +++ b/internal/puzzles/solutions/2021/day08/solution_test.go @@ -0,0 +1,117 @@ +package day08 + +import ( + "errors" + "io" + "path/filepath" + "testing" + "testing/iotest" + + "github.com/stretchr/testify/assert" + + "github.com/obalunenko/advent-of-code/internal/puzzles/common/utils" +) + +func Test_solution_Year(t *testing.T) { + var s solution + + want := "2021" + got := s.Year() + + assert.Equal(t, want, got) +} + +func Test_solution_Day(t *testing.T) { + var s solution + + want := "8" + got := s.Day() + + assert.Equal(t, want, got) +} + +func Test_solution_Part1(t *testing.T) { + var s solution + + type args struct { + input io.Reader + } + + tests := []struct { + name string + args args + want string + wantErr assert.ErrorAssertionFunc + }{ + { + name: "test example from description", + args: args{ + input: utils.ReaderFromFile(t, filepath.Join("testdata", "input.txt")), + }, + want: "26", + wantErr: assert.NoError, + }, + { + name: "", + args: args{ + input: iotest.ErrReader(errors.New("custom error")), + }, + want: "", + wantErr: assert.Error, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := s.Part1(tt.args.input) + if !tt.wantErr(t, err) { + return + } + + assert.Equal(t, tt.want, got) + }) + } +} + +func Test_solution_Part2(t *testing.T) { + var s solution + + type args struct { + input io.Reader + } + + tests := []struct { + name string + args args + want string + wantErr assert.ErrorAssertionFunc + }{ + { + name: "test example from description", + args: args{ + input: utils.ReaderFromFile(t, filepath.Join("testdata", "input.txt")), + }, + want: "", + wantErr: assert.NoError, + }, + { + name: "", + args: args{ + input: iotest.ErrReader(errors.New("custom error")), + }, + want: "", + wantErr: assert.Error, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := s.Part2(tt.args.input) + if !tt.wantErr(t, err) { + return + } + + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/internal/puzzles/solutions/2021/day08/spec.md b/internal/puzzles/solutions/2021/day08/spec.md new file mode 100644 index 00000000..a8383ed4 --- /dev/null +++ b/internal/puzzles/solutions/2021/day08/spec.md @@ -0,0 +1,90 @@ +# --- Day 8: Seven Segment Search --- + +## --- Part One --- + +You barely reach the safety of the cave when the whale smashes into the cave mouth, collapsing it. +Sensors indicate another exit to this cave at a much greater depth, so you have no choice but to press on. + +As your submarine slowly makes its way through the cave system, you notice that the four-digit seven-segment displays +in your submarine are malfunctioning; they must have been damaged during the escape. You'll be in a lot of trouble +without them, so you'd better figure out what's wrong. + +Each digit of a seven-segment display is rendered by turning on or off any of seven segments named a through g: + +```text + 0: 1: 2: 3: 4: + aaaa .... aaaa aaaa .... +b c . c . c . c b c +b c . c . c . c b c + .... .... dddd dddd dddd +e f . f e . . f . f +e f . f e . . f . f + gggg .... gggg gggg .... + + 5: 6: 7: 8: 9: + aaaa aaaa aaaa aaaa aaaa +b . b . . c b c b c +b . b . . c b c b c + dddd dddd .... dddd dddd +. f e f . f e f . f +. f e f . f e f . f + gggg gggg .... gggg gggg +``` + + +So, to render a 1, only segments c and f would be turned on; the rest would be off. To render a 7, only segments a, c, +and f would be turned on. + +The problem is that the signals which control the segments have been mixed up on each display. The submarine is still +trying to display numbers by producing output on signal wires a through g, but those wires are connected to segments +randomly. Worse, the wire/segment connections are mixed up separately for each four-digit display! +(All of the digits within a display use the same connections, though.) + +So, you might know that only signal wires b and g are turned on, but that doesn't mean segments b and g are turned on: +the only digit that uses two segments is 1, so it must mean segments c and f are meant to be on. With just that +information, you still can't tell which wire (b/g) goes to which segment (c/f). For that, you'll need to collect more +information. + +For each display, you watch the changing signals for a while, make a note of all ten unique signal patterns you see, +and then write down a single four digit output value (your puzzle input). +Using the signal patterns, you should be able to work out which pattern corresponds to which digit. + +### For example, here is what you might see in a single entry in your notes: + +```text +acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab |cdfeb fcadb cdfeb cdbaf +``` + +(The entry is wrapped here to two lines so it fits; in your notes, it will all be on a single line.) + +Each entry consists of ten unique signal patterns, a | delimiter, and finally the four digit output value. +Within an entry, the same wire/segment connections are used (but you don't know what the connections actually are). +The unique signal patterns correspond to the ten different ways the submarine tries to render a digit using the current +wire/segment connections. Because 7 is the only digit that uses three segments, dab in the above example means that to +render a 7, signal lines d, a, and b are on. Because 4 is the only digit that uses four segments, eafb means that to +render a 4, signal lines e, a, f, and b are on. + +Using this information, you should be able to work out which combination of signal wires corresponds to each of the ten +digits. Then, you can decode the four digit output value. Unfortunately, in the above example, +all of the digits in the output value (cdfeb fcadb cdfeb cdbaf) use five segments and are more difficult to deduce. + +### For now, focus on the easy digits. Consider this larger example: + +```text +be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb |fdgacbe cefdb cefbgd gcbe +edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec |fcgedb cgb dgebacf gc +fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef |cg cg fdcagb cbg +fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega |efabcd cedba gadfec cb +aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga |gecf egdcabf bgf bfgea +fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf |gebdcfa ecba ca fadegcb +dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf |cefg dcbef fcge gbcadfe +bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd |ed bcgafe cdgba cbgef +egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg |gbdfcae bgc cg cgb +gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc |fgae cfgab fg bagce +``` + +Because the digits 1, 4, 7, and 8 each use a unique number of segments, you should be able to tell which combinations +of signals correspond to those digits. Counting only digits in the output values (the part after | on each line), +in the above example, there are 26 instances of digits that use a unique number of segments (highlighted above). + +In the output values, how many times do digits 1, 4, 7, or 8 appear? \ No newline at end of file diff --git a/internal/puzzles/solutions/2021/day08/testdata/input.txt b/internal/puzzles/solutions/2021/day08/testdata/input.txt new file mode 100644 index 00000000..3a4dd13d --- /dev/null +++ b/internal/puzzles/solutions/2021/day08/testdata/input.txt @@ -0,0 +1,10 @@ +be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb |fdgacbe cefdb cefbgd gcbe +edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec |fcgedb cgb dgebacf gc +fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef |cg cg fdcagb cbg +fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega |efabcd cedba gadfec cb +aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga |gecf egdcabf bgf bfgea +fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf |gebdcfa ecba ca fadegcb +dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf |cefg dcbef fcge gbcadfe +bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd |ed bcgafe cdgba cbgef +egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg |gbdfcae bgc cg cgb +gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc |fgae cfgab fg bagce From 414d280bc7fbe0eb73a69b6ed6e2a50e5ad08ec7 Mon Sep 17 00:00:00 2001 From: Oleg Balunenko Date: Tue, 21 Dec 2021 00:13:55 +0300 Subject: [PATCH 2/2] feat(puszzles): Register solver for 2021/day08 --- internal/puzzles/solutions/register_2021.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/puzzles/solutions/register_2021.go b/internal/puzzles/solutions/register_2021.go index 0ebb5549..f3621369 100644 --- a/internal/puzzles/solutions/register_2021.go +++ b/internal/puzzles/solutions/register_2021.go @@ -18,4 +18,6 @@ import ( _ "github.com/obalunenko/advent-of-code/internal/puzzles/solutions/2021/day06" // register day07 solution. _ "github.com/obalunenko/advent-of-code/internal/puzzles/solutions/2021/day07" + // register day08 solution. + _ "github.com/obalunenko/advent-of-code/internal/puzzles/solutions/2021/day08" )