diff --git a/main.go b/main.go index 18bb35f..99020fb 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,7 @@ package main import ( "fmt" - "github.com/thatguygriff/aoc2020/twentytwo" + "github.com/thatguygriff/aoc2020/twentythree" ) func main() { @@ -92,6 +92,9 @@ func main() { // fmt.Println(twentyone.PartTwo()) // Day 22 - fmt.Println(twentytwo.PartOne()) - fmt.Println(twentytwo.PartTwo()) + // fmt.Println(twentytwo.PartOne()) + // fmt.Println(twentytwo.PartTwo()) + + // Day 23 + fmt.Println(twentythree.PartOne()) } diff --git a/twentythree/day_twentythree.go b/twentythree/day_twentythree.go new file mode 100644 index 0000000..d31f824 --- /dev/null +++ b/twentythree/day_twentythree.go @@ -0,0 +1,104 @@ +package twentythree + +import ( + "fmt" + "strconv" +) + +type game struct { + cups []int + currentCup int + highestCup int +} + +func (g *game) load(input string) error { + for _, c := range input { + cupNumber, err := strconv.Atoi(string(c)) + if err != nil { + return err + } + if cupNumber > g.highestCup { + g.highestCup = cupNumber + } + g.cups = append(g.cups, cupNumber) + } + + if len(g.cups) > 0 { + g.currentCup = g.cups[0] + } + + return nil +} + +func (g *game) play(moves int) string { + for i := 0; i < moves; i++ { + // pickup cups + pickup := g.cups[1:4] + remaining := []int{g.cups[0]} + remaining = append(remaining, g.cups[4:]...) + g.cups = remaining + + // find destination cup + destination := false + destinationIndex := -1 + t := g.currentCup - 1 + for !destination { + if t <= 0 { + t = g.highestCup + } + + for i := 1; i < len(g.cups); i++ { + if g.cups[i] == t { + destinationIndex = i + break + } + } + + if destinationIndex != -1 { + destination = true + } + t-- + } + + // place cups + newOrder := []int{} + for _, c := range remaining[:destinationIndex+1] { + newOrder = append(newOrder, c) + } + newOrder = append(newOrder, pickup...) + for _, c := range remaining[destinationIndex+1:] { + newOrder = append(newOrder, c) + } + g.cups = newOrder + + // Update current cup + g.cups = g.cups[1:] + g.cups = append(g.cups, g.currentCup) + g.currentCup = g.cups[0] + } + + return g.output() +} + +func (g *game) output() string { + state := []int{} + for i, c := range g.cups { + if c == 1 { + state = append(state, g.cups[i+1:]...) + state = append(state, g.cups[:i]...) + } + } + output := "" + for _, n := range state { + output += fmt.Sprintf("%d", n) + } + + return output +} + +// PartOne What are the labels on the cups after cup 1 +func PartOne() string { + g := game{} + g.load("418976235") + return g.play(100) +} diff --git a/twentythree/day_twentythree_test.go b/twentythree/day_twentythree_test.go new file mode 100644 index 0000000..5436d0a --- /dev/null +++ b/twentythree/day_twentythree_test.go @@ -0,0 +1,60 @@ +package twentythree + +import "testing" + +func Test_load_input(t *testing.T) { + g := game{} + g.load("32415") + + if len(g.cups) != 5 { + t.Logf("Expected 5 cups. Got %d", len(g.cups)) + t.FailNow() + } + + if g.highestCup != 5 { + t.Logf("Expected highest cup to be 5, found %d", g.highestCup) + t.FailNow() + } +} + +func Test_10_moves(t *testing.T) { + g := game{} + g.load("389125467") + + if len(g.cups) != 9 { + t.Logf("Expected 9 cups. Got %d", len(g.cups)) + t.FailNow() + } + + if g.highestCup != 9 { + t.Logf("Expected highest cup to be 9, found %d", g.highestCup) + t.FailNow() + } + + tenMoves := g.play(10) + if tenMoves != "92658374" { + t.Logf("Expected \"92658374\" but found %q", tenMoves) + t.FailNow() + } +} + +func Test_100_moves(t *testing.T) { + g := game{} + g.load("389125467") + + if len(g.cups) != 9 { + t.Logf("Expected 9 cups. Got %d", len(g.cups)) + t.FailNow() + } + + if g.highestCup != 9 { + t.Logf("Expected highest cup to be 9, found %d", g.highestCup) + t.FailNow() + } + + hundredMoves := g.play(100) + if hundredMoves != "67384529" { + t.Logf("Expected \"67384529\" but found %q", hundredMoves) + t.FailNow() + } +} \ No newline at end of file