day13.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. "strconv"
  8. "strings"
  9. )
  10. type schedule struct {
  11. timestamp int64
  12. buses map[int64]int64
  13. }
  14. func getIDs(busesString string) (map[int64]int64, error) {
  15. buses := make(map[int64]int64)
  16. for _, bus := range strings.Split(busesString, ",") {
  17. if bus == "x" {
  18. continue
  19. }
  20. busID, err := strconv.ParseInt(bus, 10, 32)
  21. if err != nil {
  22. return buses, fmt.Errorf("Error parsing busID %s: %s", bus, err)
  23. }
  24. buses[busID] = 0
  25. }
  26. return buses, nil
  27. }
  28. func readData(file *os.File) (schedule, error) {
  29. scanner := bufio.NewScanner(file)
  30. data := schedule{}
  31. if !scanner.Scan() {
  32. return data, fmt.Errorf("Error reading timestamp!")
  33. }
  34. timestampString := scanner.Text()
  35. timestamp, err := strconv.ParseInt(timestampString, 10, 32)
  36. if err != nil {
  37. return data, fmt.Errorf("Error parsing timestamp %s: %s", timestampString, err)
  38. }
  39. data.timestamp = timestamp
  40. if !scanner.Scan() {
  41. return data, fmt.Errorf("Error reading buses!")
  42. }
  43. busesString := scanner.Text()
  44. if err := scanner.Err(); err != nil {
  45. return data, err
  46. }
  47. data.buses, err = getIDs(busesString)
  48. if err != nil {
  49. return data, err
  50. }
  51. return data, nil
  52. }
  53. func calculateTimes(data schedule) schedule {
  54. for key, _ := range data.buses {
  55. data.buses[key] = key - (data.timestamp % key)
  56. }
  57. return data
  58. }
  59. func findEarliestBus(data schedule) int64 {
  60. var earliest int64 = data.timestamp
  61. var earliestID int64 = 0
  62. for key, value := range data.buses {
  63. if value < earliest {
  64. earliest = value
  65. earliestID = key
  66. }
  67. }
  68. return earliest * earliestID
  69. }
  70. func main() {
  71. if len(os.Args) < 2 {
  72. log.Fatal("You need to specify a file!")
  73. }
  74. file, err := os.Open(os.Args[1])
  75. if err != nil {
  76. log.Fatalf("Failed to open %s!\n", os.Args[1])
  77. }
  78. data, err := readData(file)
  79. if err != nil {
  80. log.Fatalf("Failed to read data: %s\n", err)
  81. }
  82. data = calculateTimes(data)
  83. fmt.Println("Part1:", findEarliestBus(data))
  84. }