code.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "os"
  6. "strconv"
  7. "strings"
  8. )
  9. func readInput(file string) map[int]int {
  10. data, err := os.ReadFile(file)
  11. if err != nil {
  12. log.Fatal(err)
  13. }
  14. stones := make(map[int]int)
  15. parts := strings.Split(strings.Trim(string(data), "\n"), " ")
  16. for _, part := range parts {
  17. stone, err := strconv.Atoi(part)
  18. if err != nil {
  19. log.Fatalf("Bad input %s: %s", part, err)
  20. }
  21. stones[stone]++
  22. }
  23. return stones
  24. }
  25. func splitStone(stoneString string) (int, int) {
  26. half := len(stoneString) / 2
  27. first, err1 := strconv.Atoi(stoneString[:half])
  28. if err1 != nil {
  29. log.Fatalf("Can't convert %s: %s", stoneString[:half], err1)
  30. }
  31. second, err2 := strconv.Atoi(stoneString[half:])
  32. if err1 != nil {
  33. log.Fatalf("Can't convert %s: %s", stoneString[half:], err2)
  34. }
  35. return first, second
  36. }
  37. func processStones(stones map[int]int) map[int]int {
  38. newStones := make(map[int]int)
  39. for key, value := range stones {
  40. if key == 0 {
  41. newStones[1] += value
  42. } else if stoneString := fmt.Sprintf("%d", key); len(stoneString)%2 == 0 {
  43. first, second := splitStone(stoneString)
  44. newStones[first] += value
  45. newStones[second] += value
  46. } else {
  47. m := key * 2024
  48. newStones[m] += value
  49. }
  50. }
  51. return newStones
  52. }
  53. func blink(stones map[int]int, blinks int) map[int]int {
  54. for i := 0; i < blinks; i++ {
  55. stones = processStones(stones)
  56. }
  57. return stones
  58. }
  59. func countStones(stones map[int]int) int {
  60. var result int
  61. for _, value := range stones {
  62. result += value
  63. }
  64. return result
  65. }
  66. func main() {
  67. if len(os.Args) < 2 {
  68. log.Fatal("You need to specify a file!")
  69. }
  70. stones := readInput(os.Args[1])
  71. part1Stones := blink(stones, 25)
  72. fmt.Println("Part1:", countStones(part1Stones))
  73. part2Stones := blink(part1Stones, 50)
  74. fmt.Println("Part2:", countStones(part2Stones))
  75. }