From c5fcc8b353fcd019ca89536e54aeba87e38323d1 Mon Sep 17 00:00:00 2001 From: Kharec Date: Sat, 6 Dec 2025 23:34:48 +0100 Subject: [PATCH] feat: solve part one --- internal/2021/DayFour/code.go | 134 ++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 internal/2021/DayFour/code.go diff --git a/internal/2021/DayFour/code.go b/internal/2021/DayFour/code.go new file mode 100644 index 0000000..cdb471a --- /dev/null +++ b/internal/2021/DayFour/code.go @@ -0,0 +1,134 @@ +package dayfour + +import ( + "os" + "strconv" + "strings" + + "advent-of-code/internal/registry" +) + +const boardSize = 5 + +func init() { + registry.Register("2021D4", ParseInput, PartOne, PartTwo) +} + +func ParseInput(filepath string) string { + content, _ := os.ReadFile(filepath) + return string(content) +} + +type board struct { + numbers [boardSize][boardSize]int + positionMap map[int][2]int + rowCounts [boardSize]int + columnCounts [boardSize]int + marked map[int]bool + won bool +} + +func newBoard() board { + return board{ + positionMap: make(map[int][2]int, boardSize*boardSize), + marked: make(map[int]bool), + } +} + +func parseBoards(lines []string) []board { + var boards []board + current := newBoard() + row := 0 + + for _, line := range lines { + line = strings.TrimSpace(line) + if line == "" { + if row == boardSize { + boards = append(boards, current) + current = newBoard() + row = 0 + } + continue + } + + fields := strings.Fields(line) + for column, field := range fields { + number, _ := strconv.Atoi(field) + current.numbers[row][column] = number + current.positionMap[number] = [2]int{row, column} + } + row++ + } + + if row == boardSize { + boards = append(boards, current) + } + + return boards +} + +func (b *board) mark(number int) bool { + if b.won { + return false + } + + position, exists := b.positionMap[number] + if !exists { + return false + } + + b.marked[number] = true + row, column := position[0], position[1] + b.rowCounts[row]++ + b.columnCounts[column]++ + + if b.rowCounts[row] == boardSize || b.columnCounts[column] == boardSize { + b.won = true + return true + } + + return false +} + +func (b *board) sumUnmarked() int { + sum := 0 + for row := range boardSize { + for column := range boardSize { + number := b.numbers[row][column] + if !b.marked[number] { + sum += number + } + } + } + return sum +} + +func parseNumbers(line string) []int { + numbersStr := strings.Split(line, ",") + numbers := make([]int, 0, len(numbersStr)) + for _, numStr := range numbersStr { + num, _ := strconv.Atoi(numStr) + numbers = append(numbers, num) + } + return numbers +} + +func PartOne(input string) int { + lines := strings.Split(strings.TrimSpace(input), "\n") + numbers := parseNumbers(lines[0]) + boards := parseBoards(lines[1:]) + + for _, number := range numbers { + for idx := range boards { + if boards[idx].mark(number) { + return boards[idx].sumUnmarked() * number + } + } + } + + return 0 +} + +func PartTwo(input string) int { + return 0 +}