Day 13: Part 1 and 2

Signed-off-by: James Griffin <james@unsupervised.ca>
This commit is contained in:
2020-12-13 14:43:04 -04:00
parent a346b4b5b6
commit 6972ec84a1
5 changed files with 226 additions and 3 deletions

10
main.go
View File

@@ -3,7 +3,7 @@ package main
import (
"fmt"
"github.com/thatguygriff/aoc2020/twelve"
"github.com/thatguygriff/aoc2020/thirteen"
)
func main() {
@@ -52,6 +52,10 @@ func main() {
// fmt.Println(eleven.PartTwo())
// Day 12
fmt.Println(twelve.PartOne())
fmt.Println(twelve.PartTwo())
// fmt.Println(twelve.PartOne())
// fmt.Println(twelve.PartTwo())
// Day 13
fmt.Println(thirteen.PartOne())
fmt.Println(thirteen.PartTwo())
}

138
thirteen/day_thirteen.go Normal file
View File

@@ -0,0 +1,138 @@
package thirteen
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type bus struct {
id int
}
type note struct {
departure int
routes []bus
sequence []int
}
func notes(f string) (*note, error) {
n := &note{}
if err := n.load(f); err != nil {
return nil, err
}
return n, nil
}
func (n *note) load(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
first := true
scanner := bufio.NewScanner(file)
for scanner.Scan() {
if first {
time, err := strconv.Atoi(scanner.Text())
if err != nil {
return err
}
n.departure = time
first = false
continue
}
buses := strings.Split(scanner.Text(), ",")
for _, b := range buses {
if b == "x" {
n.sequence = append(n.sequence, -1)
continue
}
id, err := strconv.Atoi(b)
if err != nil {
return err
}
n.routes = append(n.routes, bus{id: id})
n.sequence = append(n.sequence, id)
}
}
return nil
}
func (n *note) firstBus() int {
wait := 0
now := n.departure
for {
for _, bus := range n.routes {
if now%bus.id == 0 {
fmt.Println("Found", bus.id, "after a wait of", wait)
return wait * bus.id
}
}
now++
wait++
}
}
func (n *note) sequenceStart() int {
if len(n.sequence) == 0 {
return -1
}
time := 0
for {
// Naive interval skipping, only check times where the first bus is scheduled
interval := n.sequence[0]
found := true
for i := 1; i < len(n.sequence); i++ {
// Skip unconstrained rules
if n.sequence[i] == -1 {
continue
}
if (time+i)%n.sequence[i] == 0 {
// We know that the bus at i is correct, so we can skip interval*bus id ahead for the next time this is valid
interval *= n.sequence[i]
continue
}
// We reach this point if the sequence is broken. We now advance
// to the next time the first bus is valid
time += interval
found = false
break
}
if found {
return time
}
}
}
// PartOne find the product of the wait * bus id to get to the airport
func PartOne() string {
n, err := notes("thirteen/input.txt")
if err != nil {
return err.Error()
}
return fmt.Sprintf("Found a product of %d", n.firstBus())
}
// PartTwo What is the answer to the consequtive departure minutes contest
func PartTwo() string {
n, err := notes("thirteen/input.txt")
if err != nil {
return err.Error()
}
return fmt.Sprintf("The earliest minute is %d", n.sequenceStart())
}

View File

@@ -0,0 +1,77 @@
package thirteen
import "testing"
func Test_note_load(t *testing.T) {
n, err := notes("sample.txt")
if err != nil {
t.Logf(err.Error())
t.Fail()
}
if len(n.routes) != 5 {
t.Logf("Expected 5 routes, found %d", n.routes)
t.Fail()
}
if n.departure != 939 {
t.Logf("Expected departure of 939, found %d", n.departure)
t.Fail()
}
}
func Test_find_first(t *testing.T) {
n, _ := notes("sample.txt")
result := n.firstBus()
if result != 295 {
t.Logf("Expected product of 295 for first bus, got %d", result)
t.Fail()
}
}
func Test_contest_start(t *testing.T) {
n, _ := notes("sample.txt")
result := n.sequenceStart()
if result != 1068781 {
t.Logf("Expected time of 1068781 for sequence, got %d", result)
t.Fail()
}
n.sequence = []int{17, -1, 13, 19}
result = n.sequenceStart()
if result != 3417 {
t.Logf("Expected time of 3417 for sequence, got %d", result)
t.Fail()
}
n.sequence = []int{67, 7, 59, 61}
result = n.sequenceStart()
if result != 754018 {
t.Logf("Expected time of 754018 for sequence, got %d", result)
t.Fail()
}
n.sequence = []int{67, -1, 7, 59, 61}
result = n.sequenceStart()
if result != 779210 {
t.Logf("Expected time of 779210 for sequence, got %d", result)
t.Fail()
}
n.sequence = []int{67, 7, -1, 59, 61}
result = n.sequenceStart()
if result != 1261476 {
t.Logf("Expected time of 1261476 for sequence, got %d", result)
t.Fail()
}
n.sequence = []int{1789, 37, 47, 1889}
result = n.sequenceStart()
if result != 1202161486 {
t.Logf("Expected time of 1202161486 for sequence, got %d", result)
t.Fail()
}
}

2
thirteen/input.txt Normal file
View File

@@ -0,0 +1,2 @@
1002561
17,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,409,x,29,x,x,x,x,x,x,x,x,x,x,13,x,x,x,x,x,x,x,x,x,23,x,x,x,x,x,x,x,373,x,x,x,x,x,x,x,x,x,41,x,x,x,x,x,x,x,x,19

2
thirteen/sample.txt Normal file
View File

@@ -0,0 +1,2 @@
939
7,13,x,x,59,x,31,19