Day09
This commit is contained in:
104
2024/gareth/day09/day09.go
Normal file
104
2024/gareth/day09/day09.go
Normal 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
|
||||
}
|
||||
22
2024/gareth/day09/day09_test.go
Normal file
22
2024/gareth/day09/day09_test.go
Normal 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)
|
||||
}
|
||||
1
2024/gareth/day09/input.txt
Normal file
1
2024/gareth/day09/input.txt
Normal file
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"aoc2024/day08"
|
||||
"aoc2024/day09"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
@@ -9,9 +9,11 @@ import (
|
||||
|
||||
func main() {
|
||||
start := time.Now()
|
||||
data, _ := os.ReadFile("day08/input.txt")
|
||||
fmt.Printf("part 1: %d\n", day08.Part1(string(data)))
|
||||
fmt.Printf("part 2: %d\n", day08.Part2(string(data)))
|
||||
data, _ := os.ReadFile("day09/input.txt")
|
||||
fmt.Printf("part 1: %d\n", day09.Part1(string(data)))
|
||||
fmt.Printf("part 2: %d\n", day09.Part2(string(data)))
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Execution time: %s\n", elapsed)
|
||||
}
|
||||
|
||||
// 6320029754031
|
||||
|
||||
Reference in New Issue
Block a user