[ADD] main: Added day 9 solution
This commit is contained in:
parent
2e223f1bba
commit
c72ccb1cb3
3 changed files with 188 additions and 0 deletions
1
09/input.txt
Normal file
1
09/input.txt
Normal file
File diff suppressed because one or more lines are too long
186
09/main.go
Normal file
186
09/main.go
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"slices"
|
||||
"time"
|
||||
)
|
||||
|
||||
const FILE_PATH = "./input.txt"
|
||||
|
||||
//const FILE_PATH = "./sample.txt"
|
||||
|
||||
func LoadInput(filename string) ([]string, error) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var lines []string
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
lines = append(lines, scanner.Text())
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return lines, nil
|
||||
}
|
||||
|
||||
type structuredInput = string
|
||||
|
||||
func TransformInput(lines []string) structuredInput {
|
||||
return lines[0]
|
||||
}
|
||||
|
||||
type Block struct {
|
||||
id int
|
||||
length int
|
||||
free int
|
||||
|
||||
used int
|
||||
freeUsed int
|
||||
}
|
||||
|
||||
func Part1CreateBlocks(input structuredInput) []Block {
|
||||
var result = make([]Block, 0)
|
||||
var temp Block
|
||||
for i := 0; i < len(input); i += 2 {
|
||||
temp = Block{id: i / 2, length: int(input[i] - '0')}
|
||||
if i+1 < len(input) {
|
||||
temp.free = int(input[i+1] - '0')
|
||||
}
|
||||
result = append(result, temp)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func Part1(input structuredInput) int {
|
||||
var result = 0
|
||||
|
||||
var blocks = Part1CreateBlocks(input)
|
||||
var j = 0
|
||||
|
||||
for i := 0; i < len(blocks); i++ {
|
||||
for blocks[i].used != blocks[i].length {
|
||||
result += j * blocks[i].id
|
||||
blocks[i].used += 1
|
||||
j++
|
||||
}
|
||||
|
||||
for blocks[i].freeUsed != blocks[i].free {
|
||||
for m := len(blocks) - 1; m >= 0; m-- {
|
||||
if blocks[m].used != blocks[m].length {
|
||||
result += j * blocks[m].id
|
||||
blocks[m].used += 1
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
blocks[i].freeUsed += 1
|
||||
j++
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func findBlockWithLE(blocks []Block, size int, self int) int {
|
||||
for i := len(blocks) - 1; i >= 0; i-- {
|
||||
if blocks[i].id != self && blocks[i].length <= size {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func getIndex(blocks []Block, id int) int {
|
||||
for i, block := range blocks {
|
||||
if block.id == id {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func printBlocks(blocks []Block) {
|
||||
for i := 0; i < len(blocks); i++ {
|
||||
for j := 0; j < blocks[i].length; j++ {
|
||||
fmt.Print("|", blocks[i].id)
|
||||
}
|
||||
for j := 0; j < blocks[i].free; j++ {
|
||||
fmt.Print("|", ".")
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func Part2(input structuredInput) int {
|
||||
var result = 0
|
||||
|
||||
var blocks = Part1CreateBlocks(input)
|
||||
|
||||
var index int
|
||||
var freeHost int
|
||||
var freeUser int
|
||||
var j int
|
||||
|
||||
for i := len(blocks) - 1; i >= 0; i-- {
|
||||
index = getIndex(blocks, i)
|
||||
for j := 0; j < index; j++ {
|
||||
if blocks[j].free >= blocks[index].length {
|
||||
freeHost = blocks[j].free
|
||||
freeUser = blocks[index].free
|
||||
blocks[j].free = 0
|
||||
blocks[index].free = freeHost - blocks[index].length
|
||||
blocks = slices.Insert(blocks, j+1, blocks[index])
|
||||
blocks[index+1].id = -1
|
||||
blocks[index+1].free = freeUser + blocks[index+1].length
|
||||
blocks[index+1].length = 0
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
j = 0
|
||||
for i := 0; i < len(blocks); i++ {
|
||||
for m := 0; m < blocks[i].length; m++ {
|
||||
result += j * blocks[i].id
|
||||
j++
|
||||
}
|
||||
j += blocks[i].free
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func main() {
|
||||
var start time.Time
|
||||
var elapsed time.Duration = 0
|
||||
input, err := LoadInput(FILE_PATH)
|
||||
if err != nil {
|
||||
fmt.Println("Error loading input:", err)
|
||||
return
|
||||
}
|
||||
|
||||
structuredInput := TransformInput(input)
|
||||
fmt.Println("Structured Input:", structuredInput)
|
||||
|
||||
start = time.Now()
|
||||
fmt.Println("Solution Part 1: ", Part1(structuredInput))
|
||||
elapsed = time.Since(start)
|
||||
fmt.Printf("Part 1 took %s\n", elapsed)
|
||||
|
||||
start = time.Now()
|
||||
fmt.Println("Solution Part 2: ", Part2(structuredInput))
|
||||
elapsed = time.Since(start)
|
||||
fmt.Printf("Part 2 took %s\n", elapsed)
|
||||
}
|
||||
1
09/sample.txt
Normal file
1
09/sample.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
354631466260
|
||||
Loading…
Reference in a new issue