feat: completed day 6 for advent of code 2025
This commit is contained in:
parent
ed7885cb22
commit
9909eaf70f
4 changed files with 191 additions and 0 deletions
|
|
@ -14,6 +14,7 @@ import (
|
|||
"cpatino.com/advent-of-code/2025/day03"
|
||||
"cpatino.com/advent-of-code/2025/day04"
|
||||
"cpatino.com/advent-of-code/2025/day05"
|
||||
"cpatino.com/advent-of-code/2025/day06"
|
||||
)
|
||||
|
||||
var days = map[int]func(string) (any, any){
|
||||
|
|
@ -22,6 +23,7 @@ var days = map[int]func(string) (any, any){
|
|||
3: day03.Run,
|
||||
4: day04.Run,
|
||||
5: day05.Run,
|
||||
6: day06.Run,
|
||||
}
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
|
|
|
|||
151
2025/day06/day06.go
Executable file
151
2025/day06/day06.go
Executable file
|
|
@ -0,0 +1,151 @@
|
|||
package day06
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func findBlocks(grid [][]rune) [][2]int {
|
||||
rows, cols := len(grid), len(grid[0])
|
||||
blocks := [][2]int{}
|
||||
inBlock, blockStart := false, 0
|
||||
for col := range cols {
|
||||
isSpaceCol := true
|
||||
for row := range rows {
|
||||
if grid[row][col] != ' ' {
|
||||
isSpaceCol = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isSpaceCol && !inBlock {
|
||||
inBlock = true
|
||||
blockStart = col
|
||||
}
|
||||
if isSpaceCol && inBlock {
|
||||
inBlock = false
|
||||
blocks = append(blocks, [2]int{blockStart, col - 1})
|
||||
}
|
||||
}
|
||||
if inBlock {
|
||||
blocks = append(blocks, [2]int{blockStart, cols - 1})
|
||||
}
|
||||
return blocks
|
||||
}
|
||||
|
||||
func getOperation(grid [][]rune, start, end int) string {
|
||||
row := len(grid) - 1
|
||||
opStr := ""
|
||||
for col := start; col <= end; col++ {
|
||||
opStr += string(grid[row][col])
|
||||
}
|
||||
return strings.TrimSpace(opStr)
|
||||
}
|
||||
|
||||
func computeResult(numbers []int, opStr string) int {
|
||||
if len(numbers) == 0 || opStr == "" {
|
||||
return 0
|
||||
}
|
||||
result := numbers[0]
|
||||
for i := 1; i < len(numbers); i++ {
|
||||
switch opStr[0] {
|
||||
case '+':
|
||||
result += numbers[i]
|
||||
case '*':
|
||||
result *= numbers[i]
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func Part1(grid [][]rune) int {
|
||||
blocks := findBlocks(grid)
|
||||
total := 0
|
||||
|
||||
for _, block := range blocks {
|
||||
start, end := block[0], block[1]
|
||||
rows := len(grid)
|
||||
numbers := []int{}
|
||||
for row := 0; row < rows-1; row++ {
|
||||
numStr := ""
|
||||
for col := start; col <= end; col++ {
|
||||
numStr += string(grid[row][col])
|
||||
}
|
||||
|
||||
numStr = strings.TrimSpace(numStr)
|
||||
if numStr != "" {
|
||||
var num int
|
||||
fmt.Sscanf(numStr, "%d", &num)
|
||||
numbers = append(numbers, num)
|
||||
}
|
||||
}
|
||||
|
||||
opStr := getOperation(grid, start, end)
|
||||
total += computeResult(numbers, opStr)
|
||||
}
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
func Part2(grid [][]rune) int {
|
||||
blocks := findBlocks(grid)
|
||||
total := 0
|
||||
for _, block := range blocks {
|
||||
start, end := block[0], block[1]
|
||||
rows := len(grid)
|
||||
numbers := []int{}
|
||||
for col := end; col >= start; col-- {
|
||||
digits := []rune{}
|
||||
for row := 0; row < rows-1; row++ {
|
||||
d := grid[row][col]
|
||||
if d != ' ' {
|
||||
digits = append(digits, d)
|
||||
}
|
||||
}
|
||||
|
||||
numStr := strings.TrimSpace(string(digits))
|
||||
if numStr != "" {
|
||||
var num int
|
||||
fmt.Sscanf(numStr, "%d", &num)
|
||||
numbers = append(numbers, num)
|
||||
}
|
||||
}
|
||||
|
||||
opStr := getOperation(grid, start, end)
|
||||
total += computeResult(numbers, opStr)
|
||||
}
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
func Run(filename string) (any, any) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
lines := []string{}
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if len(line) > 0 {
|
||||
lines = append(lines, line)
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
rows := len(lines)
|
||||
grid := make([][]rune, rows)
|
||||
for i := range lines {
|
||||
grid[i] = []rune(lines[i])
|
||||
}
|
||||
|
||||
part1 := Part1(grid)
|
||||
part2 := Part2(grid)
|
||||
|
||||
return part1, part2
|
||||
}
|
||||
34
2025/day06/day06_test.go
Executable file
34
2025/day06/day06_test.go
Executable file
|
|
@ -0,0 +1,34 @@
|
|||
package day06
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type TestCase struct {
|
||||
FileName string
|
||||
Part1 any
|
||||
Part2 any
|
||||
}
|
||||
|
||||
func TestDay06(t *testing.T) {
|
||||
tests := []TestCase{
|
||||
{"test.txt", 4277556, 3263827},
|
||||
{"input.txt", 7326876294741, 10756006415204},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
if _, err := os.Stat(test.FileName); os.IsNotExist(err) {
|
||||
t.Fatalf("test file does not exist: %v", test.FileName)
|
||||
}
|
||||
|
||||
part1, part2 := Run(test.FileName)
|
||||
if test.Part1 != nil && part1 != test.Part1 {
|
||||
t.Fatalf("%s: unexpected part1:\nwant:\t%v\ngot:\t%v", test.FileName, test.Part1, part1)
|
||||
}
|
||||
|
||||
if test.Part2 != nil && part2 != test.Part2 {
|
||||
t.Fatalf("%s: unexpected part2:\nwant:\t%v\ngot:\t%v", test.FileName, test.Part2, part2)
|
||||
}
|
||||
}
|
||||
}
|
||||
4
2025/day06/test.txt
Executable file
4
2025/day06/test.txt
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
123 328 51 64
|
||||
45 64 387 23
|
||||
6 98 215 314
|
||||
* + * +
|
||||
Loading…
Add table
Add a link
Reference in a new issue