Skip to content

Commit cbf617d

Browse files
committed
[2024] Solution for Day 9
1 parent b3753ad commit cbf617d

File tree

3 files changed

+183
-1
lines changed

3 files changed

+183
-1
lines changed

2024/day09/main.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"os"
7+
"slices"
8+
9+
"github.com/kfarnung/advent-of-code/2024/lib"
10+
)
11+
12+
type file struct {
13+
id int64
14+
size int
15+
free int
16+
}
17+
18+
func part1(input string) int64 {
19+
layout := parseInput(input)
20+
21+
left := 0
22+
right := len(layout) - 1
23+
for {
24+
if left >= right {
25+
break
26+
} else if layout[left] != -1 {
27+
left++
28+
} else if layout[right] == -1 {
29+
right--
30+
} else {
31+
layout[left] = layout[right]
32+
layout[right] = -1
33+
}
34+
}
35+
36+
sum := int64(0)
37+
for i, id := range layout {
38+
if id == -1 {
39+
break
40+
}
41+
42+
sum += int64(id * i)
43+
}
44+
45+
return sum
46+
}
47+
48+
func part2(input string) int64 {
49+
layout := parseInput2(input)
50+
51+
for i := len(layout) - 1; i >= 0; {
52+
didMove := false
53+
for j := 0; j < i; j++ {
54+
if layout[j].free >= layout[i].size {
55+
toMove := layout[i]
56+
layout[i-1].free += toMove.size + toMove.free
57+
layout = slices.Delete(layout, i, i+1)
58+
59+
toMove.free = layout[j].free - toMove.size
60+
layout[j].free = 0
61+
layout = slices.Insert(layout, j+1, toMove)
62+
didMove = true
63+
break
64+
}
65+
}
66+
67+
if !didMove {
68+
i--
69+
}
70+
}
71+
72+
block := int64(0)
73+
sum := int64(0)
74+
for _, file := range layout {
75+
for i := 0; i < file.size; i++ {
76+
sum += int64(block * file.id)
77+
block++
78+
}
79+
80+
block += int64(file.free)
81+
}
82+
83+
return sum
84+
}
85+
86+
func parseInput(input string) []int {
87+
var layout []int
88+
for _, line := range lib.SplitLines(input) {
89+
if len(line) == 0 {
90+
continue
91+
}
92+
93+
for i := 0; i < len(line); i += 2 {
94+
id := i / 2
95+
size := int(line[i] - '0')
96+
97+
for j := 0; j < size; j++ {
98+
layout = append(layout, id)
99+
}
100+
101+
if i+1 < len(line) {
102+
free := int(line[i+1] - '0')
103+
for j := 0; j < free; j++ {
104+
layout = append(layout, -1)
105+
}
106+
}
107+
}
108+
}
109+
110+
return layout
111+
}
112+
113+
func parseInput2(input string) []file {
114+
var files []file
115+
for _, line := range lib.SplitLines(input) {
116+
if len(line) == 0 {
117+
continue
118+
}
119+
120+
for i := 0; i < len(line); i += 2 {
121+
file := file{
122+
id: int64(i / 2),
123+
size: int(line[i] - '0'),
124+
}
125+
126+
if i+1 < len(line) {
127+
file.free = int(line[i+1] - '0')
128+
}
129+
130+
files = append(files, file)
131+
}
132+
}
133+
134+
return files
135+
}
136+
137+
func main() {
138+
name := os.Args[1]
139+
content, err := lib.LoadFileContent(name)
140+
if err != nil {
141+
log.Fatal(err)
142+
}
143+
144+
fmt.Printf("Part 1: %d\n", part1(content))
145+
fmt.Printf("Part 2: %d\n", part2(content))
146+
}

2024/day09/main_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package main
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
"github.com/kfarnung/advent-of-code/2024/lib"
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
var input = strings.Join([]string{
12+
"2333133121414131402",
13+
"",
14+
}, "\n")
15+
16+
func TestPart1(t *testing.T) {
17+
assert.Equal(t, int64(1928), part1(input))
18+
19+
inputContent, err := lib.GetInputContent()
20+
if err != nil {
21+
t.Fatal(err)
22+
}
23+
24+
assert.Equal(t, int64(6200294120911), part1(inputContent))
25+
}
26+
27+
func TestPart2(t *testing.T) {
28+
assert.Equal(t, int64(2858), part2(input))
29+
30+
inputContent, err := lib.GetInputContent()
31+
if err != nil {
32+
t.Fatal(err)
33+
}
34+
35+
assert.Equal(t, int64(6227018762750), part2(inputContent))
36+
}

private

0 commit comments

Comments
 (0)