123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- package main
- import (
- "bufio"
- "fmt"
- "log"
- "os"
- "strconv"
- "strings"
- )
- type bus struct {
- id int64
- index int64
- }
- type schedule struct {
- timestamp int64
- buses []bus
- }
- func getIDs(busesString string) ([]bus, error) {
- buses := []bus{}
- var index int64 = 0
- for _, item := range strings.Split(busesString, ",") {
- if item != "x" {
- id, err := strconv.ParseInt(item, 10, 32)
- if err != nil {
- return buses, fmt.Errorf("Error parsing busID %s: %s", item, err)
- }
- newBus := bus{id: id, index: index}
- buses = append(buses, newBus)
- }
- index++
- }
- return buses, nil
- }
- func readData(file *os.File) (schedule, error) {
- scanner := bufio.NewScanner(file)
- data := schedule{}
- if !scanner.Scan() {
- return data, fmt.Errorf("Error reading timestamp!")
- }
- timestampString := scanner.Text()
- timestamp, err := strconv.ParseInt(timestampString, 10, 32)
- if err != nil {
- return data, fmt.Errorf("Error parsing timestamp %s: %s", timestampString, err)
- }
- data.timestamp = timestamp
- if !scanner.Scan() {
- return data, fmt.Errorf("Error reading buses!")
- }
- busesString := scanner.Text()
- if err := scanner.Err(); err != nil {
- return data, err
- }
- data.buses, err = getIDs(busesString)
- if err != nil {
- return data, err
- }
- return data, nil
- }
- func findEarliestBus(data schedule) int64 {
- var earliest int64 = data.timestamp
- var earliestID int64 = 0
- for _, item := range data.buses {
- value := item.id - (data.timestamp % item.id)
- if value < earliest {
- earliest = value
- earliestID = item.id
- }
- }
- return earliest * earliestID
- }
- func alignBuses(data schedule) int64 {
- var advance int64 = 1
- var next int64 = 1
- var current int64
- for _, item := range data.buses {
- current = next
- for {
- current += advance
- if (current+item.index)%item.id == 0 {
- next = current
- break
- }
- }
- advance *= item.id
- }
- return current
- }
- func main() {
- if len(os.Args) < 2 {
- log.Fatal("You need to specify a file!")
- }
- file, err := os.Open(os.Args[1])
- if err != nil {
- log.Fatalf("Failed to open %s!\n", os.Args[1])
- }
- data, err := readData(file)
- if err != nil {
- log.Fatalf("Failed to read data: %s\n", err)
- }
- if err := file.Close(); err != nil {
- log.Fatalf("Failed to close file: %s\n", err)
- }
- fmt.Println("Part1:", findEarliestBus(data))
- fmt.Println("Part2:", alignBuses(data))
- }
|