This commit is contained in:
Borna Rajković 2024-12-09 23:53:46 +01:00
parent 3cce4256cc
commit f84401e805
6 changed files with 169 additions and 0 deletions

View File

@ -27,3 +27,6 @@ var Day07Data string
//go:embed day_08/data.txt //go:embed day_08/data.txt
var Day08Data string var Day08Data string
//go:embed day_09/data.txt
var Day09Data string

1
day_09/data.txt Normal file

File diff suppressed because one or more lines are too long

1
day_09/example_data.txt Normal file
View File

@ -0,0 +1 @@
2333133121414131402

135
day_09/solution.go Normal file
View File

@ -0,0 +1,135 @@
package day_09
const Empty = -1
type State int
type Chunk struct {
start, length int
}
const (
ReadingValue = iota
ReadingSpace = iota
)
// task:https://adventofcode.com/2024/day/9
func SolveBasic(input string) int {
diagram := loadDiagram(input)
diagram = compress(diagram)
return hashSum(diagram)
}
// task:https://adventofcode.com/2024/day/9#part2
func SolveComplex(input string) int {
diagram := loadDiagram(input)
diagram = safeCompress(diagram)
return hashSum(diagram)
}
func hashSum(diagram []int) int {
sum := 0
for i, val := range diagram {
if val != Empty {
sum += i * val
}
}
return sum
}
func compress(diagram []int) []int {
startingCursor := 0
endingCursor := len(diagram) - 1
for {
for diagram[startingCursor] != Empty && startingCursor < endingCursor {
startingCursor++
}
for diagram[endingCursor] == Empty && startingCursor < endingCursor {
endingCursor--
}
if startingCursor >= endingCursor {
break
}
diagram[startingCursor] = diagram[endingCursor]
diagram[endingCursor] = Empty
}
return diagram
}
func safeCompress(diagram []int) []int {
value := diagram[len(diagram)-1]
for value >= 0 {
file := locateFile(diagram, value)
if hole, found := findHole(diagram, file.start, file.length); found {
copyFile(diagram, file, value, hole)
}
value--
}
return diagram
}
func copyFile(diagram []int, file Chunk, value int, hole Chunk) {
for i := 0; i < file.length; i++ {
diagram[hole.start+i] = value
diagram[file.start+i] = Empty
}
}
func findHole(diagram []int, end int, length int) (Chunk, bool) {
for i := 0; i < end; i++ {
if diagram[i] == Empty {
size := 0
for i+size < end && diagram[i+size] == Empty {
size++
}
if size >= length {
return Chunk{i, size}, true
}
}
}
return Chunk{}, false
}
func locateFile(diagram []int, value int) Chunk {
length := 0
for i := 0; i < len(diagram); i++ {
if diagram[i] == value {
start := i
for i+length < len(diagram) && diagram[i+length] == value {
length++
}
return Chunk{start, length}
}
}
panic("couldn't find the value")
}
func loadDiagram(input string) []int {
diagram := make([]int, 0, len(input)*5) // we reserve about the average we need
state := ReadingValue
currentValue := 0
for _, r := range input {
lenght := int(r - '0')
if state == ReadingValue {
for i := 0; i < lenght; i++ {
diagram = append(diagram, currentValue)
}
currentValue++
} else {
for i := 0; i < lenght; i++ {
diagram = append(diagram, Empty)
}
}
state = (state + 1) % 2
}
return diagram
}

24
day_09/solution_test.go Normal file
View File

@ -0,0 +1,24 @@
package day_09_test
import (
"advent_of_code_2024/day_09"
_ "embed"
"testing"
)
//go:embed example_data.txt
var ExampleData string
func TestBasicSolutionExample(t *testing.T) {
result := day_09.SolveBasic(ExampleData)
if result != 1928 {
t.Fatalf("Expected 1928 received %d", result)
}
}
func TestComplexSolutionExample(t *testing.T) {
result := day_09.SolveComplex(ExampleData)
if result != 2858 {
t.Fatalf("Expected 2858 received %d", result)
}
}

View File

@ -9,6 +9,7 @@ import (
"advent_of_code_2024/day_06" "advent_of_code_2024/day_06"
"advent_of_code_2024/day_07" "advent_of_code_2024/day_07"
"advent_of_code_2024/day_08" "advent_of_code_2024/day_08"
"advent_of_code_2024/day_09"
_ "embed" _ "embed"
"fmt" "fmt"
"os" "os"
@ -50,6 +51,10 @@ func main() {
fmt.Printf("Day 08. Basic: %d\n", day_08.SolveBasic(Day08Data)) // 20665830408335 fmt.Printf("Day 08. Basic: %d\n", day_08.SolveBasic(Day08Data)) // 20665830408335
case "08-complex": case "08-complex":
fmt.Printf("Day 08. Complex: %d\n", day_08.SolveComplex(Day08Data)) // 20665830408335 fmt.Printf("Day 08. Complex: %d\n", day_08.SolveComplex(Day08Data)) // 20665830408335
case "09-basic":
fmt.Printf("Day 09. Basic: %d\n", day_09.SolveBasic(Day09Data)) // 20665830408335
case "09-complex":
fmt.Printf("Day 09. Complex: %d\n", day_09.SolveComplex(Day09Data)) // 20665830408335
} }
} }