Skip to content

Commit be39c20

Browse files
committed
d4
1 parent fc695aa commit be39c20

File tree

7 files changed

+491
-0
lines changed

7 files changed

+491
-0
lines changed

2024/day04/day04.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package day04
2+
3+
import (
4+
"aoc/util"
5+
"strings"
6+
)
7+
8+
var (
9+
grid *util.InfGrid[string]
10+
)
11+
12+
func load(inputFile string) {
13+
data, _ := util.ReadFileToStringSlice(inputFile)
14+
grid = util.NewInfGrid[string]()
15+
16+
for y, line := range data {
17+
for x := 0; x < len(line); x++ {
18+
c := string(line[x])
19+
grid.Set(c, x, y)
20+
}
21+
}
22+
}
23+
24+
func part1(inputFile string) int {
25+
load(inputFile)
26+
27+
count := 0
28+
grid.VisitAll(func(val string, x, y int, dims ...int) {
29+
if val != "X" {
30+
return
31+
}
32+
33+
fs := []func(x, y int, count int, dims ...int) []string{
34+
grid.GetNMany,
35+
grid.GetEMany,
36+
grid.GetSMany,
37+
grid.GetWMany,
38+
grid.GetNEMany,
39+
grid.GetSEMany,
40+
grid.GetSWMany,
41+
grid.GetNWMany,
42+
}
43+
44+
for _, f := range fs {
45+
if strings.Join(f(x, y, 3), "") == "MAS" {
46+
count++
47+
}
48+
}
49+
})
50+
51+
return count
52+
}
53+
54+
func part2(inputFile string) int {
55+
load(inputFile)
56+
57+
totCount := 0
58+
grid.VisitAll(func(val string, x, y int, dims ...int) {
59+
if val != "A" {
60+
return
61+
}
62+
63+
count := 0
64+
if grid.Get(x-1, y-1) == "M" && grid.Get(x+1, y+1) == "S" {
65+
count++
66+
}
67+
68+
if grid.Get(x-1, y-1) == "S" && grid.Get(x+1, y+1) == "M" {
69+
count++
70+
}
71+
72+
if grid.Get(x-1, y+1) == "M" && grid.Get(x+1, y-1) == "S" {
73+
count++
74+
}
75+
76+
if grid.Get(x-1, y+1) == "S" && grid.Get(x+1, y-1) == "M" {
77+
count++
78+
}
79+
80+
if count == 2 {
81+
totCount++
82+
}
83+
84+
})
85+
86+
return totCount
87+
}

2024/day04/day04_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package day04
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func TestP1(t *testing.T) {
9+
got := part1("sample.txt")
10+
fmt.Printf("Got: %v\n", got)
11+
want := 18
12+
if got != want {
13+
t.Errorf("got %v but want %v", got, want)
14+
}
15+
}
16+
17+
func TestP1_Actual(t *testing.T) {
18+
got := part1("input.txt")
19+
fmt.Printf("Got: %v\n", got)
20+
want := 2573
21+
if got != want {
22+
t.Errorf("got %v but want %v", got, want)
23+
}
24+
}
25+
26+
func TestP2(t *testing.T) {
27+
got := part2("sample.txt")
28+
fmt.Printf("Got: %v\n", got)
29+
want := 9
30+
if got != want {
31+
t.Errorf("got %v but want %v", got, want)
32+
}
33+
}
34+
35+
func TestP2_Actual(t *testing.T) {
36+
got := part2("input.txt")
37+
fmt.Printf("Got: %v\n", got)
38+
want := 1850
39+
if got != want {
40+
t.Errorf("got %v but want %v", got, want)
41+
}
42+
}

2024/day04/input.txt

Lines changed: 140 additions & 0 deletions
Large diffs are not rendered by default.

2024/day04/input2.txt

Lines changed: 140 additions & 0 deletions
Large diffs are not rendered by default.

2024/day04/sample.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

2024/day04/sample2.txt

Whitespace-only changes.

util/grid.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,48 +578,120 @@ func (g *InfGrid[T]) GetN(x, y int, dims ...int) T {
578578
return g.Get(x, y+1, dims...)
579579
}
580580

581+
// GetNMany is like GetN but returns count values
582+
func (g *InfGrid[T]) GetNMany(x, y int, count int, dims ...int) []T {
583+
r := []T{}
584+
for i := 1; i <= count; i++ {
585+
r = append(r, g.Get(x, y+i, dims...))
586+
}
587+
return r
588+
}
589+
581590
// GetE will return the value east of the given coordinate (x+1), if the coordinate is outside the extents
582591
// of the grid returns the default value
583592
func (g *InfGrid[T]) GetE(x, y int, dims ...int) T {
584593
return g.Get(x+1, y, dims...)
585594
}
586595

596+
// GetEMany is like GetE but returns count values
597+
func (g *InfGrid[T]) GetEMany(x, y int, count int, dims ...int) []T {
598+
r := []T{}
599+
for i := 1; i <= count; i++ {
600+
r = append(r, g.Get(x+i, y, dims...))
601+
}
602+
return r
603+
}
604+
587605
// GetS will return the value south of the given coordinate (y-1), if the coordinate is outside the extents
588606
// of the grid returns the default value
589607
func (g *InfGrid[T]) GetS(x, y int, dims ...int) T {
590608
return g.Get(x, y-1, dims...)
591609
}
592610

611+
// GetSMany is like GetS but returns count values
612+
func (g *InfGrid[T]) GetSMany(x, y int, count int, dims ...int) []T {
613+
r := []T{}
614+
for i := 1; i <= count; i++ {
615+
r = append(r, g.Get(x, y-i, dims...))
616+
}
617+
return r
618+
}
619+
593620
// GetW will return the value west of the given coordinate (x-1), if the coordinate is outside the extents
594621
// of the grid returns the default value
595622
func (g *InfGrid[T]) GetW(x, y int, dims ...int) T {
596623
return g.Get(x-1, y, dims...)
597624
}
598625

626+
// GetWMany is like GetW but returns count values
627+
func (g *InfGrid[T]) GetWMany(x, y int, count int, dims ...int) []T {
628+
r := []T{}
629+
for i := 1; i <= count; i++ {
630+
r = append(r, g.Get(x-i, y, dims...))
631+
}
632+
return r
633+
}
634+
599635
// GetNE will return the value north-east of the given coordinate (x+1, y+1), if the coordinate is outside the extents
600636
// of the grid returns the default value
601637
func (g *InfGrid[T]) GetNE(x, y int, dims ...int) T {
602638
return g.Get(x+1, y+1, dims...)
603639
}
604640

641+
// GetNEMany is like GetNE but returns count values
642+
func (g *InfGrid[T]) GetNEMany(x, y int, count int, dims ...int) []T {
643+
r := []T{}
644+
for i := 1; i <= count; i++ {
645+
r = append(r, g.Get(x+i, y+i, dims...))
646+
}
647+
return r
648+
}
649+
605650
// GetSE will return the value south-east of the given coordinate (x+1, y-1), if the coordinate is outside the extents
606651
// of the grid returns the default value
607652
func (g *InfGrid[T]) GetSE(x, y int, dims ...int) T {
608653
return g.Get(x+1, y-1, dims...)
609654
}
610655

656+
// GetSEMany is like GetSE but returns count values
657+
func (g *InfGrid[T]) GetSEMany(x, y int, count int, dims ...int) []T {
658+
r := []T{}
659+
for i := 1; i <= count; i++ {
660+
r = append(r, g.Get(x+i, y-i, dims...))
661+
}
662+
return r
663+
}
664+
611665
// GetSW will return the value south-west of the given coordinate (x-1, y-1), if the coordinate is outside the extents
612666
// of the grid returns the default value
613667
func (g *InfGrid[T]) GetSW(x, y int, dims ...int) T {
614668
return g.Get(x-1, y-1, dims...)
615669
}
616670

671+
// GetSWMany is like GetSW but returns count values
672+
func (g *InfGrid[T]) GetSWMany(x, y int, count int, dims ...int) []T {
673+
r := []T{}
674+
for i := 1; i <= count; i++ {
675+
r = append(r, g.Get(x-i, y-i, dims...))
676+
}
677+
return r
678+
}
679+
617680
// GetNW will return the value north-west of the given coordinate (x-1, y+1), if the coordinate is outside the extents
618681
// of the grid returns the default value
619682
func (g *InfGrid[T]) GetNW(x, y int, dims ...int) T {
620683
return g.Get(x-1, y+1, dims...)
621684
}
622685

686+
// GetNWMany is like GetNW but returns count values
687+
func (g *InfGrid[T]) GetNWMany(x, y int, count int, dims ...int) []T {
688+
r := []T{}
689+
for i := 1; i <= count; i++ {
690+
r = append(r, g.Get(x-i, y+i, dims...))
691+
}
692+
return r
693+
}
694+
623695
// GetOrtho will return the values north, east, south, and west of the given coordinate, if a coordinate is outside
624696
// the extents of the grid it will be set to the default
625697
func (g *InfGrid[T]) GetOrtho(x, y int, dims ...int) []T {

0 commit comments

Comments
 (0)