Skip to content

Commit 8cd2795

Browse files
committed
day4: solve first part
1 parent ae2e1d7 commit 8cd2795

File tree

4 files changed

+126
-1
lines changed

4 files changed

+126
-1
lines changed

day4/example-focus.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
....XXMAS.
2+
.SAMXMS...
3+
...S..A...
4+
..A.A.MS.X
5+
XMASAMX.MM
6+
X.....XA.A
7+
S.S.S.S.SS
8+
.A.A.A.A.A
9+
..M.M.M.MM
10+
.X.X.XMASX

day4/example.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
MMMSXXMASM
2+
MSAMXMSMSA
3+
AMXSXMAAMM
4+
MSAMASMSMX
5+
XMASAMXAMM
6+
XXAMMXXAMA
7+
SMSMSASXSS
8+
SAXAMASAAA
9+
MAMMMXMMMM
10+
MXMXAXMASX

day4/main.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"os"
7+
)
8+
9+
const NEEDLE = "XMAS"
10+
11+
type point struct {
12+
y int
13+
x int
14+
}
15+
16+
func charAt(lines []string, p point) (byte, bool) {
17+
if p.y < 0 || p.x < 0 {
18+
return 0, false
19+
}
20+
if p.y >= len(lines) {
21+
return 0, false
22+
}
23+
if p.x >= len(lines[p.y]) {
24+
return 0, false
25+
}
26+
return lines[p.y][p.x], true
27+
}
28+
29+
func generateMatchPoints(at point, dy, dx int) []point {
30+
result := []point{}
31+
for i := range NEEDLE {
32+
p := point{y: at.y + dy*i, x: at.x + dx*i}
33+
result = append(result, p)
34+
}
35+
return result
36+
}
37+
38+
func matchPointGenerators() []func(point) []point {
39+
return []func(point) []point{
40+
func(p point) []point { return generateMatchPoints(p, -1, 0) },
41+
func(p point) []point { return generateMatchPoints(p, -1, -1) },
42+
func(p point) []point { return generateMatchPoints(p, 0, -1) },
43+
func(p point) []point { return generateMatchPoints(p, 1, -1) },
44+
func(p point) []point { return generateMatchPoints(p, 1, 0) },
45+
func(p point) []point { return generateMatchPoints(p, 1, 1) },
46+
func(p point) []point { return generateMatchPoints(p, 0, 1) },
47+
func(p point) []point { return generateMatchPoints(p, -1, 1) },
48+
}
49+
}
50+
51+
func isAMatch(points []point, lines []string) bool {
52+
for i, p := range points {
53+
if c, ok := charAt(lines, p); !ok || c != NEEDLE[i] {
54+
return false
55+
}
56+
}
57+
return true
58+
}
59+
60+
func countMatchesFrom(source point, lines []string, matches [][]byte) int {
61+
matchCount := 0
62+
for _, generator := range matchPointGenerators() {
63+
matchPoints := generator(source)
64+
if !isAMatch(matchPoints, lines) {
65+
continue
66+
}
67+
68+
for i, p := range matchPoints {
69+
matches[p.y][p.x] = NEEDLE[i]
70+
}
71+
matchCount++
72+
}
73+
return matchCount
74+
}
75+
76+
func main() {
77+
scanner := bufio.NewScanner(os.Stdin)
78+
scanner.Split(bufio.ScanLines)
79+
80+
var lines []string
81+
for scanner.Scan() {
82+
lines = append(lines, scanner.Text())
83+
}
84+
85+
matches := make([][]byte, len(lines))
86+
for y := range lines {
87+
matches[y] = make([]byte, len(lines[y]))
88+
for x := range lines[y] {
89+
matches[y][x] = byte('.')
90+
}
91+
}
92+
93+
matchCount := 0
94+
for y := range lines {
95+
line := lines[y]
96+
for x := range line {
97+
matchCount += countMatchesFrom(point{y: y, x: x}, lines, matches)
98+
}
99+
}
100+
101+
fmt.Fprintf(os.Stderr, "matches: %d\n", matchCount)
102+
for _, lineMatches := range matches {
103+
fmt.Printf("%s\n", string(lineMatches))
104+
}
105+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module github.com/fxnn/adventofcode2024
22

3-
go 1.23.2
3+
go 1.23

0 commit comments

Comments
 (0)