-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
118 lines (105 loc) · 2.58 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
import (
"fmt"
aoc "github.com/shraddhaag/aoc/library"
)
func main() {
input := aoc.ReadFileLineByLine("input3.txt")
fmt.Println("answer for part 1: ", calculateChecksum(moveFileBlocks(generateFileBlock(input[0]))))
// fmt.Println("answer for part 2: ", calculateChecksum(moveFileBlocks2(generateFileBlock(input[0]))))
fmt.Println("answer for part 2: ", calculateUpdatedCheckSum(performFileCompaction(getHeapsAndFiles(input[0]))))
}
func generateFileBlock(input string) []int {
fileBlock := []int{}
for index, char := range input {
for _ = range aoc.FetchNumFromStringIgnoringNonNumeric(string(char)) {
// even positions are files
if index%2 == 0 {
fileBlock = append(fileBlock, index/2)
} else {
fileBlock = append(fileBlock, -1)
}
}
}
return fileBlock
}
func moveFileBlocks(block []int) []int {
start, end := 0, len(block)-1
for start < end {
if block[start] == -1 && block[end] != -1 {
block[start], block[end] = block[end], block[start]
start++
end--
continue
}
if block[start] != -1 {
start++
}
if block[end] == -1 {
end--
}
}
return block
}
func writeFile(block []int, fileNum int, fileLength int, index int) {
for i := range fileLength {
block[index+i] = fileNum
}
}
func clearFile(block []int, length int, index int) {
for i := range length {
block[index+i] = -1
}
}
func calculateChecksum(input []int) int {
sum := 0
for index, fileNumber := range input {
if fileNumber == -1 {
continue
}
sum += index * fileNumber
}
return sum
}
func moveFile(fileBlock []int, length int, originalStartIndex int) {
freeSpaceCount := 0
freeSpaceStartIndex := -1
for i := 1; i <= originalStartIndex; i++ {
if fileBlock[i-1] == -1 && fileBlock[i] != -1 {
if freeSpaceCount >= length {
writeFile(fileBlock, fileBlock[originalStartIndex], length, freeSpaceStartIndex)
clearFile(fileBlock, length, originalStartIndex)
}
freeSpaceStartIndex = -1
freeSpaceCount = 0
}
if fileBlock[i] == -1 {
freeSpaceCount++
if freeSpaceStartIndex == -1 {
freeSpaceStartIndex = i
}
}
}
}
func moveFileBlocks2(fileBlock []int) []int {
currentFile := -1
currentFileLength := 0
for i := len(fileBlock) - 1; i > 0; i-- {
if fileBlock[i] != -1 {
currentFileLength += 1
currentFile = i
if fileBlock[i] != fileBlock[i-1] {
if currentFileLength != 0 {
moveFile(fileBlock, currentFileLength, currentFile)
currentFileLength = 0
}
}
} else {
if currentFileLength != 0 {
moveFile(fileBlock, currentFileLength, currentFile)
currentFileLength = 0
}
}
}
return fileBlock
}