diff --git a/challenge/day16/a.go b/challenge/day16/a.go new file mode 100644 index 0000000..9d7b593 --- /dev/null +++ b/challenge/day16/a.go @@ -0,0 +1,64 @@ +package day16 + +import ( + "fmt" + "math" + "strconv" + "strings" + + "github.com/nlowe/aoc2019/util" + + "github.com/nlowe/aoc2019/challenge" + "github.com/spf13/cobra" +) + +var A = &cobra.Command{ + Use: "16a", + Short: "Day 16, Problem A", + Run: func(_ *cobra.Command, _ []string) { + fmt.Printf("Answer: %s\n", a(challenge.FromFile())) + }, +} + +const iterations = 100 + +var pattern = [4]int{0, 1, 0, -1} + +func a(challenge *challenge.Input) string { + in := <-challenge.Lines() + + data := make([]int, len(in)) + for i, r := range in { + data[i] = util.MustAtoI(string(r)) + } + + for i := 0; i < iterations; i++ { + data = fft(data) + } + + result := strings.Builder{} + for i := 0; i < 8; i++ { + result.WriteString(strconv.Itoa(data[i])) + } + + return result.String() +} + +func fft(in []int) []int { + result := make([]int, len(in)) + + for i := 0; i < len(in); i++ { + sum := 0 + for j := i; j < len(in); j++ { + sum += in[j] * mixin(j, i) + } + + result[i] = int(math.Abs(float64(sum))) % 10 + } + + return result +} + +func mixin(offset, iteration int) int { + return pattern[((1+offset)/(1+iteration))%len(pattern)] +} diff --git a/challenge/day16/a_test.go b/challenge/day16/a_test.go new file mode 100644 index 0000000..085d3c0 --- /dev/null +++ b/challenge/day16/a_test.go @@ -0,0 +1,25 @@ +package day16 + +import ( + "testing" + + "github.com/nlowe/aoc2019/challenge" + "github.com/stretchr/testify/require" +) + +func TestA(t *testing.T) { + tests := []struct { + in string + out string + }{ + {in: "80871224585914546619083218645595", out: "24176176"}, + {in: "19617804207202209144916044189917", out: "73745418"}, + {in: "69317163492948606335995924319873", out: "52432133"}, + } + + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + require.Equal(t, tt.out, a(challenge.FromLiteral(tt.in))) + }) + } +} diff --git a/challenge/day16/b.go b/challenge/day16/b.go new file mode 100644 index 0000000..22c1d03 --- /dev/null +++ b/challenge/day16/b.go @@ -0,0 +1,59 @@ +package day16 + +import ( + "fmt" + "strconv" + "strings" + + "github.com/nlowe/aoc2019/challenge" + "github.com/nlowe/aoc2019/util" + "github.com/spf13/cobra" +) + +var B = &cobra.Command{ + Use: "16b", + Short: "Day 16, Problem B", + Run: func(_ *cobra.Command, _ []string) { + fmt.Printf("Answer: %s\n", b(challenge.FromFile())) + }, +} + +func b(challenge *challenge.Input) string { + in := strings.Repeat(<-challenge.Lines(), 10000) + + data := make([]int, len(in)) + for i, r := range in { + data[i] = util.MustAtoI(string(r)) + } + + offset := util.MustAtoI(in[:7]) + data = data[offset:] + for i := 0; i < iterations; i++ { + data = shortcut(data) + } + + result := strings.Builder{} + for i := 0; i < 8; i++ { + result.WriteString(strconv.Itoa(data[i])) + } + + return result.String() +} + +// TODO: Here be vodo. I need to read up on why this works. +// this was mostly pieced together from posts on the +// subreddit. +func shortcut(in []int) []int { + cumulativeSum := 0 + for _, v := range in { + cumulativeSum += v + } + + var result []int + for i := range in { + result = append(result, ((cumulativeSum%10)+10)%10) + cumulativeSum -= in[i] + } + + return result +} diff --git a/challenge/day16/b_test.go b/challenge/day16/b_test.go new file mode 100644 index 0000000..ba51fe6 --- /dev/null +++ b/challenge/day16/b_test.go @@ -0,0 +1,25 @@ +package day16 + +import ( + "testing" + + "github.com/nlowe/aoc2019/challenge" + "github.com/stretchr/testify/require" +) + +func TestB(t *testing.T) { + tests := []struct { + in string + out string + }{ + {in: "03036732577212944063491565474664", out: "84462026"}, + {in: "02935109699940807407585447034323", out: "78725270"}, + {in: "03081770884921959731165446850517", out: "53553731"}, + } + + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + require.Equal(t, tt.out, b(challenge.FromLiteral(tt.in))) + }) + } +} diff --git a/challenge/day16/input.txt b/challenge/day16/input.txt new file mode 100644 index 0000000..d723c14 --- /dev/null +++ b/challenge/day16/input.txt @@ -0,0 +1 @@ +59776034095811644545367793179989602140948714406234694972894485066523525742503986771912019032922788494900655855458086979764617375580802558963587025784918882219610831940992399201782385674223284411499237619800193879768668210162176394607502218602633153772062973149533650562554942574593878073238232563649673858167635378695190356159796342204759393156294658366279922734213385144895116649768185966866202413314939692174223210484933678866478944104978890019728562001417746656699281992028356004888860103805472866615243544781377748654471750560830099048747570925902575765054898899512303917159138097375338444610809891667094051108359134017128028174230720398965960712 diff --git a/main.go b/main.go index 05a6f6f..ccbf17c 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,8 @@ import ( "fmt" "time" + "github.com/nlowe/aoc2019/challenge/day16" + "github.com/nlowe/aoc2019/challenge/day15" "github.com/nlowe/aoc2019/challenge/day14" @@ -74,6 +76,7 @@ func init() { day13.A, day13.B, day14.A, day14.B, day15.A, day15.B, + day16.A, day16.B, ) flags := rootCmd.PersistentFlags()