diff --git a/d3/d3.go b/d3/d3.go index f7d9905..a0d94a7 100644 --- a/d3/d3.go +++ b/d3/d3.go @@ -36,3 +36,45 @@ func D3(input string) int64 { return gammaNum * epsilonNum } + +func rating(binaries []string, position int, path func([]string, []string) []string) string { + if len(binaries) == 1 { + return binaries[0] + } + + ones := make([]string, 0, len(binaries)/2) // allocate at least half original slice + zeroes := make([]string, 0, len(binaries)/2) + for _, binary := range binaries { + if binary[position] == '1' { + ones = append(ones, binary) + } else { + zeroes = append(zeroes, binary) + + } + } + + return rating(path(ones, zeroes), position+1, path) +} + +func D3P2(input string) int64 { + binaries := strings.Split(strings.TrimSpace(input), "\n") + + o2predicate := func(ones, zeroes []string) []string { + if len(ones) == len(zeroes) || len(ones) > len(zeroes) { + return ones + } + return zeroes + } + + co2predicate := func(ones, zeroes []string) []string { + if len(ones) == len(zeroes) || len(ones) > len(zeroes) { + return zeroes + } + return ones + } + + o2rating, _ := strconv.ParseInt(rating(binaries, 0, o2predicate), 2, 64) + co2rating, _ := strconv.ParseInt(rating(binaries, 0, co2predicate), 2, 64) + + return o2rating * co2rating +} diff --git a/d3/d3_test.go b/d3/d3_test.go index 9a0e844..6358365 100644 --- a/d3/d3_test.go +++ b/d3/d3_test.go @@ -23,3 +23,21 @@ func TestD3(t *testing.T) { assert.EqualValues(t, 198, D3(input)) } + +func TestD3P2(t *testing.T) { + input := ` +00100 +11110 +10110 +10111 +10101 +01111 +00111 +11100 +10000 +11001 +00010 +01010` + + assert.EqualValues(t, 230, D3P2(input)) +} diff --git a/main.go b/main.go index a123941..2bfbc9f 100644 --- a/main.go +++ b/main.go @@ -27,5 +27,6 @@ func main() { fmt.Printf("day 2: %v\n", d2.D2(client.Day(2))) fmt.Printf("day 2 part 2: %v\n", d2.D2P2(client.Day(2))) fmt.Printf("day 3: %v\n", d3.D3(client.Day(3))) + fmt.Printf("day 3 part 2: %v\n", d3.D3P2(client.Day(3))) }