package main import ( "fmt" "git.mstar.dev/mstar/aoc24/util" "git.mstar.dev/mstar/goutils/sliceutils" ) type Coord struct { X, Y int C rune } // Ugly but works var allOffsets1 = [][]Coord{ {newCoord(0, 0, 'X'), newCoord(0, 1, 'M'), newCoord(0, 2, 'A'), newCoord(0, 3, 'S')}, {newCoord(0, 0, 'X'), newCoord(0, -1, 'M'), newCoord(0, -2, 'A'), newCoord(0, -3, 'S')}, {newCoord(0, 0, 'X'), newCoord(1, 0, 'M'), newCoord(2, 0, 'A'), newCoord(3, 0, 'S')}, {newCoord(0, 0, 'X'), newCoord(-1, 0, 'M'), newCoord(-2, 0, 'A'), newCoord(-3, 0, 'S')}, {newCoord(0, 0, 'X'), newCoord(1, 1, 'M'), newCoord(2, 2, 'A'), newCoord(3, 3, 'S')}, {newCoord(0, 0, 'X'), newCoord(-1, -1, 'M'), newCoord(-2, -2, 'A'), newCoord(-3, -3, 'S')}, {newCoord(0, 0, 'X'), newCoord(1, -1, 'M'), newCoord(2, -2, 'A'), newCoord(3, -3, 'S')}, {newCoord(0, 0, 'X'), newCoord(-1, 1, 'M'), newCoord(-2, 2, 'A'), newCoord(-3, 3, 'S')}, } var allOffsets2 = [][]Coord{ { newCoord(0, 0, 'A'), newCoord(-1, -1, 'M'), newCoord(-1, 1, 'M'), newCoord(1, 1, 'S'), newCoord(1, -1, 'S'), }, { newCoord(0, 0, 'A'), newCoord(-1, -1, 'S'), newCoord(-1, 1, 'M'), newCoord(1, 1, 'M'), newCoord(1, -1, 'S'), }, { newCoord(0, 0, 'A'), newCoord(-1, -1, 'S'), newCoord(-1, 1, 'S'), newCoord(1, 1, 'M'), newCoord(1, -1, 'M'), }, { newCoord(0, 0, 'A'), newCoord(-1, -1, 'M'), newCoord(-1, 1, 'S'), newCoord(1, 1, 'S'), newCoord(1, -1, 'M'), }, } func newCoord(x, y int, C rune) Coord { return Coord{x, y, C} } func linesToGrid(lines []string) [][]rune { return sliceutils.Map(lines, func(t string) []rune { return []rune(t) }) } func safeAccess(grid [][]rune, x, y int) (bool, rune) { if x < 0 { return false, ' ' } if y < 0 { return false, ' ' } if x >= len(grid[0]) { return false, ' ' } if y >= len(grid) { return false, ' ' } return true, grid[y][x] } func checkGridWithOffsets(x, y int, grid [][]rune, allOffsets [][]Coord) int { acc := 0 outer: for _, offsets := range allOffsets { for _, offset := range offsets { ok, r := safeAccess(grid, x+offset.X, y+offset.Y) if !ok { continue outer } if offset.C != r { continue outer } } acc++ } if acc != 0 { // fmt.Printf("Found %d at %d:%d\n", acc, x, y) } return acc } func main() { grid := linesToGrid(util.FileContentToNonEmptyLines(util.LoadFileFromArgs())) counter := 0 for iy := range grid { for ix := range grid[iy] { counter += checkGridWithOffsets(ix, iy, grid, allOffsets1) } } fmt.Printf("Task 1: %d\n", counter) counter = 0 for iy := range grid { for ix := range grid[iy] { counter += checkGridWithOffsets(ix, iy, grid, allOffsets2) } } fmt.Printf("Task 2: %d\n", counter) }