Skip to content

Commit 17d9a6d

Browse files
committed
day9: solve part two
1 parent 9dc0117 commit 17d9a6d

File tree

1 file changed

+79
-9
lines changed

1 file changed

+79
-9
lines changed

Diff for: day9/main.go

+79-9
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ func printDiskBlocks(diskBlocks []int) {
3939
fmt.Printf("%d", b)
4040
}
4141
}
42+
fmt.Println()
4243
}
4344

4445
func compact(in []int) []int {
@@ -60,7 +61,7 @@ func compact(in []int) []int {
6061
return out
6162
}
6263

63-
func checksum(diskBlocks []int) int {
64+
func calculateChecksum(diskBlocks []int) int {
6465
var checksum = 0
6566
for i, b := range diskBlocks {
6667
if b != FREE {
@@ -70,21 +71,90 @@ func checksum(diskBlocks []int) int {
7071
return checksum
7172
}
7273

74+
func findFreeSpace(blocks []int, size int) int {
75+
var targetBegin, foundSize int
76+
targetBegin = -1
77+
for i := range blocks {
78+
if blocks[i] == FREE && targetBegin == -1 {
79+
targetBegin = i
80+
}
81+
if blocks[i] != FREE && targetBegin != -1 {
82+
foundSize = i - targetBegin
83+
if foundSize >= size {
84+
return targetBegin
85+
}
86+
targetBegin = -1
87+
}
88+
}
89+
return -1
90+
}
91+
92+
func set(blocks []int, begin, end, fileId int) {
93+
for i := begin; i <= end; i++ {
94+
blocks[i] = fileId
95+
}
96+
}
97+
98+
func defrag(in []int) []int {
99+
var out = make([]int, len(in))
100+
copy(out[:], in[:])
101+
102+
var fileId, sourceBegin, sourceEnd int
103+
fileId = -1
104+
for i := len(in) - 1; i >= 0; i-- {
105+
if fileId > 0 && fileId != in[i] {
106+
// case 1: we've exited the file
107+
var size, targetBegin int
108+
109+
sourceBegin = i + 1
110+
size = sourceEnd - sourceBegin + 1
111+
112+
targetBegin = findFreeSpace(out, size)
113+
if targetBegin >= 0 && targetBegin < sourceBegin {
114+
fmt.Printf(" move: %d -> %d (size %d)\n", sourceBegin, targetBegin, size)
115+
set(out, sourceBegin, sourceEnd, FREE)
116+
set(out, targetBegin, targetBegin+size-1, fileId)
117+
} else {
118+
fmt.Printf(" stay: %d (size %d)\n", sourceBegin, size)
119+
}
120+
fileId = -1
121+
}
122+
if fileId < 0 {
123+
if in[i] == FREE {
124+
// case 2: we're crossing void areas
125+
continue
126+
}
127+
// case 3: we're entering the file
128+
fileId = in[i]
129+
sourceEnd = i
130+
}
131+
}
132+
return out
133+
}
134+
73135
func main() {
74136
scanner := bufio.NewScanner(os.Stdin)
75137
scanner.Split(bufio.ScanLines)
76138

139+
var diskMap string
77140
scanner.Scan()
78-
var diskMap = scanner.Text()
141+
diskMap = scanner.Text()
79142

80-
var diskBlocks = calculateDiskBlocks(diskMap)
143+
var diskBlocks []int
144+
diskBlocks = calculateDiskBlocks(diskMap)
81145
printDiskBlocks(diskBlocks)
82-
fmt.Println()
83146

84-
diskBlocks = compact(diskBlocks)
85-
printDiskBlocks(diskBlocks)
86-
fmt.Println()
147+
var compactDiskBlocks []int
148+
var compactChecksum int
149+
compactDiskBlocks = compact(diskBlocks)
150+
printDiskBlocks(compactDiskBlocks)
151+
compactChecksum = calculateChecksum(compactDiskBlocks)
152+
fmt.Printf("compact checksum: %d\n", compactChecksum)
87153

88-
var checksum = checksum(diskBlocks)
89-
fmt.Printf("checksum: %d\n", checksum)
154+
var defragDiskBlocks []int
155+
var defragChecksum int
156+
defragDiskBlocks = defrag(diskBlocks)
157+
printDiskBlocks(defragDiskBlocks)
158+
defragChecksum = calculateChecksum(defragDiskBlocks)
159+
fmt.Printf("defrag checksum: %d\n", defragChecksum)
90160
}

0 commit comments

Comments
 (0)