mirror of
https://github.com/onyx-and-iris/aoc2024.git
synced 2026-04-08 18:13:36 +00:00
add day-09 + benchmarks
This commit is contained in:
6
day-09/internal/one/benchmark
Normal file
6
day-09/internal/one/benchmark
Normal file
@@ -0,0 +1,6 @@
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
pkg: github.com/onyx-and-iris/aoc2024/day-09/internal/one
|
||||
cpu: Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz
|
||||
BenchmarkSolve-12 1000000000 0.1535 ns/op
|
||||
ok github.com/onyx-and-iris/aoc2024/day-09/internal/one 1.893s
|
||||
8
day-09/internal/one/block.go
Normal file
8
day-09/internal/one/block.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package one
|
||||
|
||||
const empty = -1
|
||||
|
||||
type block struct {
|
||||
used int
|
||||
free int
|
||||
}
|
||||
59
day-09/internal/one/disk.go
Normal file
59
day-09/internal/one/disk.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package one
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type disk struct {
|
||||
data []int
|
||||
totalUsed int
|
||||
}
|
||||
|
||||
func newDisk(blocks []block) disk {
|
||||
var totalUsed int
|
||||
data := []int{}
|
||||
for id, block := range blocks {
|
||||
for range block.used {
|
||||
data = append(data, id)
|
||||
}
|
||||
for range block.free {
|
||||
data = append(data, empty)
|
||||
}
|
||||
totalUsed += block.used
|
||||
}
|
||||
|
||||
return disk{
|
||||
data: data,
|
||||
totalUsed: totalUsed,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *disk) len() int {
|
||||
return d.totalUsed
|
||||
}
|
||||
|
||||
func (d *disk) sort() {
|
||||
for i := len(d.data) - 1; i >= 0; i-- {
|
||||
if d.data[i] != empty {
|
||||
indx := slices.Index(d.data, empty)
|
||||
if indx == d.len() {
|
||||
break
|
||||
}
|
||||
d.data[i], d.data[indx] = d.data[indx], d.data[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *disk) debug() string {
|
||||
var sb strings.Builder
|
||||
for _, n := range d.data {
|
||||
if n == empty {
|
||||
sb.WriteRune('.')
|
||||
} else {
|
||||
sb.WriteString(fmt.Sprintf("%d", n))
|
||||
}
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
27
day-09/internal/one/solve.go
Normal file
27
day-09/internal/one/solve.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package one
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func Solve(buf []byte) (int, error) {
|
||||
r := bytes.NewReader(buf)
|
||||
blocks, err := parseLines(r)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
disk := newDisk(blocks)
|
||||
disk.sort()
|
||||
log.Debug(disk.debug())
|
||||
|
||||
var i, checksum int
|
||||
for range disk.len() {
|
||||
checksum += i * disk.data[i]
|
||||
i++
|
||||
}
|
||||
|
||||
return checksum, nil
|
||||
}
|
||||
15
day-09/internal/one/solve_internal_test.go
Normal file
15
day-09/internal/one/solve_internal_test.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package one
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
//go:embed testdata/input.txt
|
||||
var data []byte
|
||||
|
||||
func BenchmarkSolve(b *testing.B) {
|
||||
os.Stdout, _ = os.Open(os.DevNull)
|
||||
Solve(data)
|
||||
}
|
||||
38
day-09/internal/one/util.go
Normal file
38
day-09/internal/one/util.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package one
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func parseLines(r io.Reader) ([]block, error) {
|
||||
var blocks []block
|
||||
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
for i := 0; i < len(line); i += 2 {
|
||||
var free int
|
||||
if i < len(line)-1 {
|
||||
free = mustConv(string(line[i+1]))
|
||||
}
|
||||
blocks = append(blocks, block{mustConv(string(line[i])), free})
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return []block{}, err
|
||||
}
|
||||
|
||||
return blocks, nil
|
||||
}
|
||||
|
||||
func mustConv(s string) int {
|
||||
n, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
Reference in New Issue
Block a user