code.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. "os"
  7. "strings"
  8. )
  9. func readInput(file string) []string {
  10. content, err := ioutil.ReadFile(file)
  11. if err != nil {
  12. log.Fatal(err)
  13. }
  14. lines := strings.Split(string(content), "\n")
  15. return lines
  16. }
  17. var points map[rune]int
  18. func init() {
  19. points = make(map[rune]int)
  20. points[')'] = 3
  21. points[']'] = 57
  22. points['}'] = 1197
  23. points['>'] = 25137
  24. }
  25. func parseLine(line string) rune {
  26. opened := make(map[rune]int)
  27. var lastOpened []rune
  28. for _, char := range line {
  29. if char == '(' || char == '[' || char == '{' || char == '<' {
  30. opened[char]++
  31. lastOpened = append(lastOpened, char)
  32. continue
  33. }
  34. if len(lastOpened) == 0 {
  35. return char
  36. }
  37. switch char {
  38. case ')':
  39. if lastOpened[len(lastOpened)-1] != '(' {
  40. return char
  41. }
  42. case ']':
  43. if lastOpened[len(lastOpened)-1] != '[' {
  44. return char
  45. }
  46. case '}':
  47. if lastOpened[len(lastOpened)-1] != '{' {
  48. return char
  49. }
  50. case '>':
  51. if lastOpened[len(lastOpened)-1] != '<' {
  52. return char
  53. }
  54. }
  55. lastOpened = lastOpened[:len(lastOpened)-1]
  56. }
  57. return ' '
  58. }
  59. func part1(input []string) (int, []string) {
  60. var total int
  61. var incomplete []string
  62. for _, line := range input {
  63. illegal := parseLine(line)
  64. if illegal != ' ' {
  65. total += points[illegal]
  66. continue
  67. }
  68. incomplete = append(incomplete, line)
  69. }
  70. return total, incomplete
  71. }
  72. func fixLine(line string) rune {
  73. opened := make(map[rune]int)
  74. var lastOpened []rune
  75. for _, char := range line {
  76. if char == '(' || char == '[' || char == '{' || char == '<' {
  77. opened[char]++
  78. lastOpened = append(lastOpened, char)
  79. continue
  80. }
  81. if len(lastOpened) == 0 {
  82. return char
  83. }
  84. switch char {
  85. case ')':
  86. if lastOpened[len(lastOpened)-1] != '(' {
  87. return char
  88. }
  89. case ']':
  90. if lastOpened[len(lastOpened)-1] != '[' {
  91. return char
  92. }
  93. case '}':
  94. if lastOpened[len(lastOpened)-1] != '{' {
  95. return char
  96. }
  97. case '>':
  98. if lastOpened[len(lastOpened)-1] != '<' {
  99. return char
  100. }
  101. }
  102. lastOpened = lastOpened[:len(lastOpened)-1]
  103. }
  104. return ' '
  105. }
  106. func main() {
  107. if len(os.Args) < 2 {
  108. log.Fatal("Please provide a file name as argument")
  109. }
  110. input := readInput(os.Args[1])
  111. total, incomplete := part1(input)
  112. fmt.Println("Part 1:", total)
  113. fmt.Println(len(incomplete))
  114. }