day7.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. "regexp"
  8. "strconv"
  9. "strings"
  10. )
  11. type Bag struct {
  12. count int64
  13. name string
  14. }
  15. func getBags(line string, bags map[string][]Bag) {
  16. bugNameRegex := regexp.MustCompile(`(\w+\s\w+) bags contain `)
  17. result := bugNameRegex.FindStringSubmatch(line)
  18. if len(result) != 2 {
  19. return
  20. }
  21. bagName := result[1]
  22. bugContainsRegex := regexp.MustCompile(`(\d+)\s(\w+\s\w+)`)
  23. subStrings := strings.Split(line, ", ")
  24. for _, sub := range subStrings {
  25. subResult := bugContainsRegex.FindStringSubmatch(sub)
  26. if len(subResult) != 3 {
  27. continue
  28. }
  29. number, err := strconv.ParseInt(subResult[1], 10, 32)
  30. if err != nil {
  31. continue
  32. }
  33. bags[bagName] = append(bags[bagName], Bag{name: subResult[2], count: number})
  34. }
  35. }
  36. func readFile(filePath string, bags map[string][]Bag) {
  37. file, err := os.Open(filePath)
  38. if err != nil {
  39. log.Fatalf("failed to open")
  40. }
  41. scanner := bufio.NewScanner(file)
  42. for scanner.Scan() {
  43. line := scanner.Text()
  44. getBags(line, bags)
  45. }
  46. if err := scanner.Err(); err != nil {
  47. log.Println(err)
  48. }
  49. }
  50. func checkBag(phrase string, bagName string, bags map[string][]Bag) bool {
  51. for _, bag := range bags[bagName] {
  52. if bag.name == phrase {
  53. return true
  54. }
  55. if checkBag(phrase, bag.name, bags) {
  56. return true
  57. }
  58. }
  59. return false
  60. }
  61. func countBagsContaining(phrase string, bags map[string][]Bag) int {
  62. count := 0
  63. for name, _ := range bags {
  64. if name == phrase {
  65. continue
  66. }
  67. if checkBag(phrase, name, bags) {
  68. count++
  69. }
  70. }
  71. return count
  72. }
  73. func countBagsIn(bag string, bags map[string][]Bag) int64 {
  74. var count int64 = 0
  75. for _, value := range bags[bag] {
  76. count += value.count
  77. count += value.count * countBagsIn(value.name, bags)
  78. }
  79. return count
  80. }
  81. func main() {
  82. if len(os.Args) < 2 {
  83. log.Fatal("You need to specify a file!")
  84. }
  85. var bags = make(map[string][]Bag)
  86. readFile(os.Args[1], bags)
  87. fmt.Println("Part1:", countBagsContaining("shiny gold", bags))
  88. fmt.Println("Part2:", countBagsIn("shiny gold", bags))
  89. }