code.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. )
  8. type Point struct {
  9. y, x int
  10. }
  11. type Pattern struct {
  12. note [][]byte
  13. mirror Point
  14. }
  15. func readInput(file *os.File) []Pattern {
  16. scanner := bufio.NewScanner(file)
  17. var patterns []Pattern
  18. var current Pattern
  19. for scanner.Scan() {
  20. line := scanner.Text()
  21. if line == "" {
  22. patterns = append(patterns, current)
  23. current = Pattern{}
  24. continue
  25. }
  26. var row []byte
  27. for i := range line {
  28. row = append(row, line[i])
  29. }
  30. current.note = append(current.note, row)
  31. }
  32. patterns = append(patterns, current)
  33. return patterns
  34. }
  35. func checkVertical(index int, note [][]byte, width int) bool {
  36. left := 0
  37. prev := index - 1
  38. right := index + prev
  39. if right >= width {
  40. right = width - 1
  41. }
  42. for {
  43. if prev < left || index > right {
  44. break
  45. }
  46. for i := range note {
  47. if note[i][prev] != note[i][index] {
  48. return false
  49. }
  50. }
  51. prev--
  52. index++
  53. }
  54. return true
  55. }
  56. func checkHorizontal(index int, note [][]byte, height int, width int) bool {
  57. up := 0
  58. prev := index - 1
  59. down := index + prev
  60. if down >= height {
  61. down = height - 1
  62. }
  63. for {
  64. if prev < up || index > down {
  65. break
  66. }
  67. for i := range note[index] {
  68. if note[index][i] != note[prev][i] {
  69. return false
  70. }
  71. }
  72. prev--
  73. index++
  74. }
  75. return true
  76. }
  77. func part1(patterns []Pattern) int {
  78. var result int
  79. for i := range patterns {
  80. width := len(patterns[i].note[0])
  81. height := len(patterns[i].note)
  82. gotVertical := false
  83. for index := 1; index < width; index++ {
  84. if checkVertical(index, patterns[i].note, width) {
  85. result += index
  86. gotVertical = true
  87. break
  88. }
  89. }
  90. if gotVertical {
  91. continue
  92. }
  93. for index := 1; index < height; index++ {
  94. if checkHorizontal(index, patterns[i].note, height, width) {
  95. result += index * 100
  96. break
  97. }
  98. }
  99. }
  100. return result
  101. }
  102. func main() {
  103. if len(os.Args) < 2 {
  104. log.Fatal("You need to specify a file!")
  105. }
  106. filePath := os.Args[1]
  107. file, err := os.Open(filePath)
  108. if err != nil {
  109. log.Fatalf("Failed to open %s!\n", filePath)
  110. }
  111. patterns := readInput(file)
  112. fmt.Println("Part1:", part1(patterns))
  113. }