⭐ Created part two solution for day 15 puzzle
This commit is contained in:
parent
ef35183f2e
commit
e292edaf62
|
@ -9,6 +9,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"source.toby3d.me/toby3d/adventofcode/internal/day15/part1"
|
||||
"source.toby3d.me/toby3d/adventofcode/internal/day15/part2"
|
||||
)
|
||||
|
||||
var input []byte
|
||||
|
@ -26,3 +27,8 @@ func Example() {
|
|||
fmt.Println(part1.ParseSequence(bytes.NewReader(input)).Sum())
|
||||
// Output: 514639
|
||||
}
|
||||
|
||||
func Example_PartTwo() {
|
||||
fmt.Println(part2.ParseSequence(bytes.NewReader(input)).Sum())
|
||||
// Output: 279470
|
||||
}
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
package part2
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"slices"
|
||||
)
|
||||
|
||||
type (
|
||||
Sequence []Step
|
||||
|
||||
Step []byte
|
||||
|
||||
Lens struct {
|
||||
label []byte
|
||||
length int
|
||||
}
|
||||
)
|
||||
|
||||
func (s Step) Sum() uint {
|
||||
var result uint
|
||||
|
||||
for i := range s.Hash() {
|
||||
result += uint(s[i])
|
||||
result *= 17
|
||||
result = result % 256
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (s Step) IsRemove() bool {
|
||||
return bytes.IndexByte(s, '-') != -1
|
||||
}
|
||||
|
||||
func (s Step) IsMove() bool {
|
||||
return bytes.IndexByte(s, '=') != -1
|
||||
}
|
||||
|
||||
func (s Step) Hash() []byte {
|
||||
return s[:max(bytes.IndexByte(s, '-'), bytes.IndexByte(s, '='))]
|
||||
}
|
||||
|
||||
func (s Step) Length() int {
|
||||
index := max(bytes.IndexByte(s, '-'), bytes.IndexByte(s, '='))
|
||||
if index == len(s)-1 {
|
||||
return 0
|
||||
}
|
||||
|
||||
return int(s[index+1] - '0')
|
||||
}
|
||||
|
||||
func (s Sequence) Sum() uint64 {
|
||||
var boxes [256][]Lens
|
||||
|
||||
for i := range s {
|
||||
box := &boxes[int(s[i].Sum())]
|
||||
index := slices.IndexFunc(*box, func(l Lens) bool {
|
||||
return bytes.Equal(l.label, s[i].Hash())
|
||||
})
|
||||
|
||||
switch {
|
||||
default:
|
||||
continue
|
||||
case s[i].IsRemove() && index != -1:
|
||||
*box = slices.Delete(*box, index, index+1)
|
||||
case s[i].IsMove():
|
||||
if index != -1 {
|
||||
(*box)[index] = Lens{
|
||||
label: s[i].Hash(),
|
||||
length: s[i].Length(),
|
||||
}
|
||||
} else {
|
||||
*box = append(*box, Lens{
|
||||
label: s[i].Hash(),
|
||||
length: s[i].Length(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var result int
|
||||
for i := range boxes {
|
||||
for j := range boxes[i] {
|
||||
result += (i + 1) * (j + 1) * boxes[i][j].length
|
||||
}
|
||||
}
|
||||
|
||||
return uint64(result)
|
||||
}
|
||||
|
||||
func ParseSequence(r io.Reader) Sequence {
|
||||
scanner := bufio.NewScanner(r)
|
||||
scanner.Split(bufio.ScanBytes)
|
||||
|
||||
seq := make(Sequence, 0)
|
||||
step := make(Step, 0)
|
||||
|
||||
for scanner.Scan() {
|
||||
b := scanner.Bytes()[0]
|
||||
switch b {
|
||||
case ',', '\n':
|
||||
seq = append(seq, step)
|
||||
step = make(Step, 0)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
step = append(step, b)
|
||||
}
|
||||
|
||||
return seq
|
||||
}
|
||||
|
||||
func (s Step) GoString() string {
|
||||
return string(s)
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package part2_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"source.toby3d.me/toby3d/adventofcode/internal/day15/part2"
|
||||
)
|
||||
|
||||
func TestStep_Hash(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for name, tc := range map[string]struct {
|
||||
expect string
|
||||
input part2.Step
|
||||
}{
|
||||
"rn=1": {input: part2.Step("rn=1"), expect: "rn"},
|
||||
"cm-": {input: part2.Step("cm-"), expect: "cm"},
|
||||
"qp=3": {input: part2.Step("qp=3"), expect: "qp"},
|
||||
"cm=2": {input: part2.Step("cm=2"), expect: "cm"},
|
||||
"qp-": {input: part2.Step("qp-"), expect: "qp"},
|
||||
"pc=4": {input: part2.Step("pc=4"), expect: "pc"},
|
||||
"ot=9": {input: part2.Step("ot=9"), expect: "ot"},
|
||||
"ab=5": {input: part2.Step("ab=5"), expect: "ab"},
|
||||
"pc-": {input: part2.Step("pc-"), expect: "pc"},
|
||||
"pc=6": {input: part2.Step("pc=6"), expect: "pc"},
|
||||
"ot=7": {input: part2.Step("ot=7"), expect: "ot"},
|
||||
} {
|
||||
name, tc := name, tc
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if actual := string(tc.input.Hash()); actual != tc.expect {
|
||||
t.Errorf("want '%s', got '%s'", tc.expect, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStep_Length(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for name, tc := range map[string]struct {
|
||||
input part2.Step
|
||||
expect int
|
||||
}{
|
||||
"rn=1": {input: part2.Step("rn=1"), expect: 1},
|
||||
"cm-": {input: part2.Step("cm-"), expect: 0},
|
||||
"qp=3": {input: part2.Step("qp=3"), expect: 3},
|
||||
"cm=2": {input: part2.Step("cm=2"), expect: 2},
|
||||
"qp-": {input: part2.Step("qp-"), expect: 0},
|
||||
"pc=4": {input: part2.Step("pc=4"), expect: 4},
|
||||
"ot=9": {input: part2.Step("ot=9"), expect: 9},
|
||||
"ab=5": {input: part2.Step("ab=5"), expect: 5},
|
||||
"pc-": {input: part2.Step("pc-"), expect: 0},
|
||||
"pc=6": {input: part2.Step("pc=6"), expect: 6},
|
||||
"ot=7": {input: part2.Step("ot=7"), expect: 7},
|
||||
} {
|
||||
name, tc := name, tc
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if actual := tc.input.Length(); actual != tc.expect {
|
||||
t.Errorf("want %d, got %d", tc.expect, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStep_IsRemove(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if actual := part2.Step("qp-").IsRemove(); !actual {
|
||||
t.Errorf("want %t, got %t", true, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStep_IsMove(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if actual := part2.Step("rn=1").IsMove(); !actual {
|
||||
t.Errorf("want %t, got %t", true, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func Example() {
|
||||
input := "rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7\n"
|
||||
seq := part2.ParseSequence(strings.NewReader(input))
|
||||
|
||||
fmt.Println(seq.Sum())
|
||||
// Output: 145
|
||||
}
|
Loading…
Reference in New Issue