diff options
| author | omagdy <omar.professional8777@gmail.com> | 2024-12-12 18:31:50 +0200 |
|---|---|---|
| committer | omagdy <omar.professional8777@gmail.com> | 2024-12-12 18:31:50 +0200 |
| commit | 0cb12b95ef11fe283731e862e3953f27eeea8757 (patch) | |
| tree | 66d54e44b821073ddf6381bf9b3d9d55b3d86c31 /2024/go/src/day09 | |
| parent | 93cc02c058f39d370472dfe7d667ae7a2f6396b3 (diff) | |
| download | aoc-0cb12b95ef11fe283731e862e3953f27eeea8757.tar.xz aoc-0cb12b95ef11fe283731e862e3953f27eeea8757.zip | |
Day 11 done.
Diffstat (limited to '2024/go/src/day09')
| -rw-r--r-- | 2024/go/src/day09/main.go | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/2024/go/src/day09/main.go b/2024/go/src/day09/main.go new file mode 100644 index 0000000..db2d99a --- /dev/null +++ b/2024/go/src/day09/main.go @@ -0,0 +1,169 @@ +package main + +import ( + "fmt" + "os" + "strconv" +) + +func InsertAt(arr *[]FileBlock, index int, value FileBlock) error { + if index < 0 || index > len(*arr) { + return fmt.Errorf("index out of range") + } + *arr = append((*arr)[:index], append([]FileBlock{value}, (*arr)[index:]...)...) + return nil +} + +func RemoveAt(arr *[]FileBlock, index int) (FileBlock, error) { + if index < 0 || index >= len(*arr) { + return FileBlock{}, fmt.Errorf("index out of range") + } + ele := (*arr)[index] + *arr = append((*arr)[:index], (*arr)[index+1:]...) + return ele, nil +} + +func FileRead(path string) string { + file, err := os.ReadFile(path) + if err != nil { + fmt.Println("Couldn't Read file: ", err) + } + return string(file) + +} + +func parseInput(data string) string { + return data +} + +func genereateBlockMap(diskMap string) []string { + var blockMap []string + id := 0 + for i, ch := range diskMap { + rep, _ := strconv.Atoi(string(ch)) + if i%2 == 0 { + for i := 0; i < rep; i++ { + blockMap = append(blockMap, strconv.Itoa(id)) + } + id += 1 + } else { + for i := 0; i < rep; i++ { + blockMap = append(blockMap, ".") + } + } + } + return blockMap +} + +func genereateFileBlocks(diskMap string) []FileBlock { + var fileBlocks []FileBlock + id := 0 + for i, ch := range diskMap { + rep, _ := strconv.Atoi(string(ch)) + if i%2 == 0 { + block := FileBlock{id: id, space: rep} + fileBlocks = append(fileBlocks, block) + id += 1 + } else { + block := FileBlock{id: -1, space: rep} + if rep > 0 { + fileBlocks = append(fileBlocks, block) + } + } + } + return fileBlocks +} + +func moveBlocks(blockMap []string) { + i := 0 + j := len(blockMap) - 1 + for i < j { + if blockMap[i] == "." { + if blockMap[j] != "." { + blockMap[i], blockMap[j] = blockMap[j], blockMap[i] + i++ + } + j-- + } else { + i++ + } + } +} + +type FileBlock struct { + id int // id -1 will be the free block '.' + space int +} + +func moveBlocksPartTwo(fileBlocks []FileBlock) []string { + for i := 0; i < len(fileBlocks); i++ { + if fileBlocks[i].id != -1 { + continue + } + for j := len(fileBlocks) - 1; j >= i; j-- { + if fileBlocks[j].id == -1 { + continue + } + if fileBlocks[i].space == fileBlocks[j].space { + fileBlocks[i], fileBlocks[j] = fileBlocks[j], fileBlocks[i] + i++ + j-- + break + } else if fileBlocks[i].space > fileBlocks[j].space { + _ = InsertAt(&fileBlocks, i+1, FileBlock{id: -1, space: fileBlocks[i].space - fileBlocks[j].space}) + spaceJ := fileBlocks[j+1].space + fileBlocks[i], fileBlocks[j+1] = fileBlocks[j+1], fileBlocks[i] + fileBlocks[j+1].id = -1 + fileBlocks[j+1].space = spaceJ + break + } + } + } + var blocks []string + for _, block := range fileBlocks { + if block.id == -1 { + for i := 0; i < block.space; i++ { + blocks = append(blocks, ".") + } + } else { + for i := 0; i < block.space; i++ { + blocks = append(blocks, strconv.Itoa(block.id)) + } + } + } + return blocks +} + +func checkSum(blockMap []string) int64 { + var sum int64 = 0 + for i, ch := range blockMap { + if ch == "." { + continue + } + id, _ := strconv.Atoi(ch) + sum += int64(id) * int64(i) + } + return sum +} +func solve_part_one(data string) int64 { + diskMap := parseInput(data) + blockMap := genereateBlockMap(diskMap) + moveBlocks(blockMap) + return checkSum(blockMap) +} + +func solve_part_two(data string) int64 { + diskMap := parseInput(data) + fileBlocks := genereateFileBlocks(diskMap) + blocks := moveBlocksPartTwo(fileBlocks) + return checkSum(blocks) +} + +func main() { + test := FileRead("../input/day09.test") + prod := FileRead("../input/day09.prod") + fmt.Println("Part_1 test: ", solve_part_one(test)) + fmt.Println("Part_1 prod: ", solve_part_one(prod)) + fmt.Println("Part_2 test: ", solve_part_two(test)) + fmt.Println("Part_2 prod: ", solve_part_two(prod)) +} |
