This commit is contained in:
Gareth
2025-01-11 16:06:38 +00:00
parent 305ce52a98
commit 4619bc7775
4 changed files with 133 additions and 4 deletions

104
2024/gareth/day09/day09.go Normal file
View File

@@ -0,0 +1,104 @@
package day09
func Part1(input string) int {
files, gaps, lengthOfFinalFile := parseInput(input)
checksum := compactFiles(files, gaps, lengthOfFinalFile)
return checksum
}
func Part2(input string) int {
files, freeSpaces := parseInputPart2(input)
checksum := calculateChecksum(files, freeSpaces)
return checksum
}
func parseInput(input string) ([]int, []int, int) {
var files []int
var gaps []int
lengthOfFinalFile := 0
for i, char := range input {
if i%2 == 0 {
files = append(files, int(char-'0'))
lengthOfFinalFile += int(char - '0')
} else {
gaps = append(gaps, int(char-'0'))
}
}
return files, gaps, lengthOfFinalFile
}
func parseInputPart2(input string) ([][]int, [][]int) {
files, freeSpaces, position := [][]int{}, [][]int{}, 0
for index, char := range input {
length := int(char - '0')
if index%2 == 0 {
files = append(files, generateRange(position, position+length))
} else {
freeSpaces = append(freeSpaces, generateRange(position, position+length))
}
position += length
}
return files, freeSpaces
}
func compactFiles(files []int, gaps []int, lengthOfFinalFile int) int {
fileIndex := len(files) - 1
gapIndex := 0
position := files[0]
checksum := 0
fileID := files[0]
for lengthOfFinalFile != position {
// If there's a gap and a file to move then move the file
if gaps[gapIndex] > 0 && files[fileIndex] > 0 {
files[fileIndex]--
gaps[gapIndex]--
checksum += fileIndex * position
position++
}
// If this file is fully moved go to next file
if files[fileIndex] == 0 {
fileIndex--
fileID++
}
// Update gapIndex if this gap is filled
if gaps[gapIndex] == 0 {
gapIndex++
for f := 0; f < files[gapIndex]; f++ {
checksum += gapIndex * position
position++
}
}
}
return checksum
}
func generateRange(start, end int) []int {
rangeList := make([]int, end-start)
for i := range rangeList {
rangeList[i] = start + i
}
return rangeList
}
func calculateChecksum(files, freeSpaces [][]int) int {
checksum := 0
for fileIndex := len(files) - 1; fileIndex >= 0; fileIndex-- {
for spaceIndex := 0; spaceIndex < len(freeSpaces); spaceIndex++ {
if len(freeSpaces[spaceIndex]) >= len(files[fileIndex]) && files[fileIndex][0] > freeSpaces[spaceIndex][0] {
files[fileIndex] = freeSpaces[spaceIndex][:len(files[fileIndex])]
freeSpaces[spaceIndex] = freeSpaces[spaceIndex][len(files[fileIndex]):]
}
}
}
for fileID, file := range files {
for _, block := range file {
checksum += fileID * block
}
}
return checksum
}

View File

@@ -0,0 +1,22 @@
package day09
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestPart1(t *testing.T) {
r := Part1(`12345`)
assert.Equal(t, 60, r)
}
func TestPart1Long(t *testing.T) {
r := Part1(`2333133121414131402`)
assert.Equal(t, 1928, r)
}
func TestPart2(t *testing.T) {
r := Part2(`2333133121414131402`)
assert.Equal(t, 2858, r)
}

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
package main package main
import ( import (
"aoc2024/day08" "aoc2024/day09"
"fmt" "fmt"
"os" "os"
"time" "time"
@@ -9,9 +9,11 @@ import (
func main() { func main() {
start := time.Now() start := time.Now()
data, _ := os.ReadFile("day08/input.txt") data, _ := os.ReadFile("day09/input.txt")
fmt.Printf("part 1: %d\n", day08.Part1(string(data))) fmt.Printf("part 1: %d\n", day09.Part1(string(data)))
fmt.Printf("part 2: %d\n", day08.Part2(string(data))) fmt.Printf("part 2: %d\n", day09.Part2(string(data)))
elapsed := time.Since(start) elapsed := time.Since(start)
fmt.Printf("Execution time: %s\n", elapsed) fmt.Printf("Execution time: %s\n", elapsed)
} }
// 6320029754031