diff --git a/main.go b/main.go index 8bd5d6e..69ae9ad 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,7 @@ package main import ( "fmt" - "github.com/thatguygriff/aoc2020/twentyone" + "github.com/thatguygriff/aoc2020/twentytwo" ) func main() { @@ -88,6 +88,9 @@ func main() { // fmt.Println(twenty.PartTwo()) // Day 21 - fmt.Println(twentyone.PartOne()) - fmt.Println(twentyone.PartTwo()) + // fmt.Println(twentyone.PartOne()) + // fmt.Println(twentyone.PartTwo()) + + // Day 22 + fmt.Println(twentytwo.PartOne()) } diff --git a/twentytwo/day_twentytwo.go b/twentytwo/day_twentytwo.go new file mode 100644 index 0000000..71de121 --- /dev/null +++ b/twentytwo/day_twentytwo.go @@ -0,0 +1,103 @@ +package twentytwo + +import ( + "bufio" + "fmt" + "os" + "strconv" +) + +type player struct { + deck []int +} + +func (p *player) score() int { + score := 0 + for i := 0; i < len(p.deck); i++ { + score += p.deck[i] * (len(p.deck) - i) + } + + return score +} + +type combat struct { + one, two player +} + +func (c *combat) load(filename string) error { + file, err := os.Open(filename) + if err != nil { + return err + } + defer file.Close() + + one := false + two := false + scanner := bufio.NewScanner(file) + for scanner.Scan() { + if scanner.Text() == "Player 1:" { + one = true + continue + } + + if scanner.Text() == "" { + one = false + two = false + continue + } + + if scanner.Text() == "Player 2:" { + two = true + continue + } + + card, err := strconv.Atoi(scanner.Text()) + if err != nil { + return err + } + + if one { + c.one.deck = append(c.one.deck, card) + } else if two { + c.two.deck = append(c.two.deck, card) + } + } + + return nil +} + +func (c *combat) play() (round int) { + for { + round++ + + // play cards + played := []int{c.one.deck[0], c.two.deck[0]} + c.one.deck = c.one.deck[1:] + c.two.deck = c.two.deck[1:] + + if played[0] > played[1] { + c.one.deck = append(c.one.deck, played[0], played[1]) + } else if played[0] < played[1] { + c.two.deck = append(c.two.deck, played[1], played[0]) + } else { + panic("TIES ARE LIKELY IN PART 2") + } + + if len(c.one.deck) == 0 || len(c.two.deck) == 0 { + break + } + } + + return round +} + +// PartOne What is the winning player's score +func PartOne() string { + c := combat{} + if err := c.load("twentytwo/input.txt"); err != nil { + return err.Error() + } + + rounds := c.play() + return fmt.Sprintf("The game lasted %d rounds with a score of %d - %d", rounds, c.one.score(), c.two.score()) +} diff --git a/twentytwo/day_twentytwo_test.go b/twentytwo/day_twentytwo_test.go new file mode 100644 index 0000000..21b357c --- /dev/null +++ b/twentytwo/day_twentytwo_test.go @@ -0,0 +1,30 @@ +package twentytwo + +import "testing" + +func Test_load_combat(t *testing.T) { + c := combat{} + if err := c.load("sample.txt"); err != nil { + t.Logf(err.Error()) + t.FailNow() + } + + if len(c.one.deck) != 5 || len(c.two.deck) != 5 { + t.Logf("Expected decks of 5 and 5, got %d and %d", len(c.one.deck), len(c.two.deck)) + } +} + +func Test_combat_play(t *testing.T) { + c := combat{} + if err := c.load("sample.txt"); err != nil { + t.Logf(err.Error()) + t.FailNow() + } + + c.play() + + if c.one.score() != 0 || c.two.score() != 306 { + t.Logf("Expected score of 0-306, got %d-%d", c.one.score(), c.two.score()) + t.Fail() + } +} diff --git a/twentytwo/input.txt b/twentytwo/input.txt new file mode 100644 index 0000000..5e0fae5 --- /dev/null +++ b/twentytwo/input.txt @@ -0,0 +1,53 @@ +Player 1: +19 +22 +43 +38 +23 +21 +2 +40 +31 +17 +27 +28 +35 +44 +41 +47 +50 +7 +39 +5 +42 +25 +33 +3 +48 + +Player 2: +16 +24 +36 +6 +34 +11 +8 +30 +26 +15 +9 +10 +14 +1 +12 +4 +32 +13 +18 +46 +37 +29 +20 +45 +49 \ No newline at end of file diff --git a/twentytwo/sample.txt b/twentytwo/sample.txt new file mode 100644 index 0000000..24d78bf --- /dev/null +++ b/twentytwo/sample.txt @@ -0,0 +1,13 @@ +Player 1: +9 +2 +6 +3 +1 + +Player 2: +5 +8 +4 +7 +10 \ No newline at end of file