chore: imporivements
This commit is contained in:
parent
127e9c33c6
commit
927fabebfc
|
@ -4,21 +4,12 @@ import (
|
|||
"bufio"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
aoc "go.sour.is/advent-of-code-2023"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result, err := aoc.Runner(run)
|
||||
if err != nil {
|
||||
fmt.Println("ERR", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
}
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
type result struct {
|
||||
sum int
|
||||
|
|
|
@ -51,12 +51,10 @@ func run(scan *bufio.Scanner) (*result, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
games = append(games, []gameResult{})
|
||||
rounds := aoc.SliceMap(func(text string) gameResult {
|
||||
round := gameResult{}
|
||||
|
||||
for _, round := range strings.Split(text, ";") {
|
||||
game := gameResult{}
|
||||
|
||||
for _, result := range strings.Split(round, ",") {
|
||||
for _, result := range strings.Split(text, ",") {
|
||||
ns, color, _ := strings.Cut(strings.TrimSpace(result), " ")
|
||||
n, err := strconv.Atoi(ns)
|
||||
if err != nil {
|
||||
|
@ -65,16 +63,17 @@ func run(scan *bufio.Scanner) (*result, error) {
|
|||
|
||||
switch color {
|
||||
case "red":
|
||||
game.red = n
|
||||
round.red = n
|
||||
case "green":
|
||||
game.green = n
|
||||
round.green = n
|
||||
case "blue":
|
||||
game.blue = n
|
||||
round.blue = n
|
||||
}
|
||||
|
||||
}
|
||||
games[len(games)-1] = append(games[len(games)-1], game)
|
||||
}
|
||||
return round
|
||||
}, strings.Split(text, ";")...)
|
||||
|
||||
games = append(games, rounds)
|
||||
}
|
||||
|
||||
aoc.Log(games)
|
||||
|
|
|
@ -9,6 +9,8 @@ import (
|
|||
aoc "go.sour.is/advent-of-code-2023"
|
||||
)
|
||||
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
type partNumber struct {
|
||||
number int
|
||||
row int
|
||||
|
@ -54,7 +56,6 @@ func (tab symbolTab) scanSymbol(p partNumber) bool {
|
|||
// 553079
|
||||
// 84363105
|
||||
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
type result struct {
|
||||
valuePT1 int
|
||||
|
@ -101,21 +102,23 @@ func run(scan *bufio.Scanner) (*result, error) {
|
|||
}
|
||||
}
|
||||
|
||||
sum := 0
|
||||
for i, p := range parts {
|
||||
ok := symbols.scanSymbol(p)
|
||||
parts[i].hasSymbol = ok
|
||||
if ok {
|
||||
sum += p.number
|
||||
}
|
||||
}
|
||||
sum := aoc.SumIFunc(
|
||||
func(i int, p partNumber) int {
|
||||
ok := symbols.scanSymbol(p)
|
||||
parts[i].hasSymbol = ok
|
||||
if ok {
|
||||
return p.number
|
||||
}
|
||||
return 0
|
||||
}, parts...,)
|
||||
|
||||
sumGears := 0
|
||||
for _, s := range symbolList {
|
||||
if s.symbol == '*' && len(s.adjacentParts) == 2 {
|
||||
sumGears += s.adjacentParts[0].number * s.adjacentParts[1].number
|
||||
}
|
||||
}
|
||||
sumGears := aoc.SumFunc(
|
||||
func(s *symbol) int {
|
||||
if s.symbol == '*' && len(s.adjacentParts) == 2 {
|
||||
return s.adjacentParts[0].number * s.adjacentParts[1].number
|
||||
}
|
||||
return 0
|
||||
}, symbolList...)
|
||||
|
||||
// fmt.Println(parts)
|
||||
// fmt.Println(symbols)
|
||||
|
|
|
@ -2,13 +2,12 @@ package main
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
aoc "go.sour.is/advent-of-code-2023"
|
||||
)
|
||||
|
||||
//go:embed input.txt
|
||||
|
@ -21,22 +20,14 @@ type card struct {
|
|||
copies int
|
||||
}
|
||||
|
||||
func main() {
|
||||
var level slog.Level
|
||||
if err := level.UnmarshalText([]byte(os.Getenv("DEBUG_LEVEL"))); err == nil && level != 0 {
|
||||
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: level})))
|
||||
}
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
buf := bytes.NewReader(input)
|
||||
scan := bufio.NewScanner(buf)
|
||||
|
||||
points, cards := run(scan)
|
||||
|
||||
fmt.Println("points:", points)
|
||||
fmt.Println("cards:", cards)
|
||||
type result struct {
|
||||
points int
|
||||
cards int
|
||||
}
|
||||
|
||||
func run(scan *bufio.Scanner) (int, int) {
|
||||
func run(scan *bufio.Scanner) (result, error) {
|
||||
cards := []*card{}
|
||||
|
||||
for scan.Scan() {
|
||||
|
@ -46,7 +37,7 @@ func run(scan *bufio.Scanner) (int, int) {
|
|||
continue
|
||||
}
|
||||
|
||||
num, _ := strconv.Atoi(strings.TrimSpace(strings.SplitN(pfx, " ", 2)[1]))
|
||||
num := aoc.Atoi(strings.TrimSpace(strings.SplitN(pfx, " ", 2)[1]))
|
||||
cards = append(cards, &card{card: num})
|
||||
buf := make([]rune, 0, 4)
|
||||
winner := true
|
||||
|
@ -71,7 +62,7 @@ func run(scan *bufio.Scanner) (int, int) {
|
|||
}
|
||||
|
||||
if len(buf) > 0 {
|
||||
num, _ = strconv.Atoi(string(buf))
|
||||
num = aoc.Atoi(string(buf))
|
||||
buf = buf[:0]
|
||||
_ = buf // ignore
|
||||
cards[len(cards)-1].scratch = append(cards[len(cards)-1].scratch, num)
|
||||
|
@ -105,5 +96,5 @@ func run(scan *bufio.Scanner) (int, int) {
|
|||
slog.Debug("points", "card", card.card, "match", m, "score", sumPoints)
|
||||
}
|
||||
|
||||
return sumPoints, sumCards
|
||||
return result{sumPoints, sumCards}, nil
|
||||
}
|
||||
|
|
|
@ -7,27 +7,19 @@ import (
|
|||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
aoc "go.sour.is/advent-of-code-2023"
|
||||
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Fprintln(os.Stderr, "Usage: day05 FILE")
|
||||
}
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
input, err := os.Open(os.Args[1])
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
|
||||
scan := bufio.NewScanner(input)
|
||||
|
||||
minLocation, minRangeLocation := run(scan)
|
||||
|
||||
fmt.Println("min location:", minLocation)
|
||||
fmt.Println("min range location:", minRangeLocation)
|
||||
type result struct {
|
||||
minLocation int
|
||||
minRange int
|
||||
}
|
||||
|
||||
func run(scan *bufio.Scanner) (int, int) {
|
||||
func run(scan *bufio.Scanner) (result, error) {
|
||||
log("begin...")
|
||||
|
||||
var seeds []int
|
||||
|
@ -55,15 +47,14 @@ func run(scan *bufio.Scanner) (int, int) {
|
|||
lookup["humidity-to-location"],
|
||||
)
|
||||
|
||||
return findMinLocation(seeds, find), FindMinRangeLocationMulti(seedRanges, find)
|
||||
return result{findMinLocation(seeds, find), FindMinRangeLocationMulti(seedRanges, find)}, nil
|
||||
}
|
||||
|
||||
func readSeeds(text string) ([]int, [][2]int) {
|
||||
var seeds [] int
|
||||
var seeds []int
|
||||
var seedRanges [][2]int
|
||||
sp := strings.Fields(strings.TrimPrefix(text, "seeds: "))
|
||||
for i, s := range sp {
|
||||
n, _ := strconv.Atoi(s)
|
||||
|
||||
for i, n := range aoc.SliceMap(aoc.Atoi, strings.Fields(strings.TrimPrefix(text, "seeds: "))...) {
|
||||
seeds = append(seeds, n)
|
||||
|
||||
if i%2 == 0 {
|
||||
|
@ -121,7 +112,7 @@ func FindMinRangeLocation(ranges [][2]int, find *Finder) int {
|
|||
|
||||
for _, s := range ranges {
|
||||
for i := 0; i < s[1]; i++ {
|
||||
seedLocations = append(seedLocations, find.Find(s[0] + i))
|
||||
seedLocations = append(seedLocations, find.Find(s[0]+i))
|
||||
}
|
||||
}
|
||||
return min(seedLocations...)
|
||||
|
@ -164,7 +155,7 @@ func FindMinRangeLocationMulti(ranges [][2]int, find *Finder) int {
|
|||
seedLocations := make([]int, 0, results)
|
||||
expectResults := make([]struct{}, len(ranges))
|
||||
for range expectResults {
|
||||
r := <- resultsCh
|
||||
r := <-resultsCh
|
||||
seedLocations = append(seedLocations, r...)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,29 +3,19 @@ package main
|
|||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
|
||||
aoc "go.sour.is/advent-of-code-2023"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Fprintln(os.Stderr, "Usage: day07 FILE")
|
||||
}
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
input, err := os.Open(os.Args[1])
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
|
||||
scan := bufio.NewScanner(input)
|
||||
|
||||
score1, score2 := run(scan)
|
||||
|
||||
fmt.Println("score 1", score1)
|
||||
fmt.Println("score 2", score2)
|
||||
type result struct {
|
||||
valuePT1 uint64
|
||||
valuePT2 uint64
|
||||
}
|
||||
|
||||
func run(scan *bufio.Scanner) (uint64, uint64) {
|
||||
func run(scan *bufio.Scanner) (result, error) {
|
||||
var game Game
|
||||
|
||||
for scan.Scan() {
|
||||
|
@ -47,7 +37,7 @@ func run(scan *bufio.Scanner) (uint64, uint64) {
|
|||
game.wildCard = 'J'
|
||||
product2 := calcProduct(game)
|
||||
|
||||
return product1, product2
|
||||
return result{product1, product2}, nil
|
||||
}
|
||||
|
||||
var cardTypes1 = []rune{'A', 'K', 'Q', 'J', 'T', '9', '8', '7', '6', '5', '4', '3', '2'}
|
||||
|
|
|
@ -54,19 +54,21 @@ func TestExample(t *testing.T) {
|
|||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(example))
|
||||
|
||||
score1, score2 := run(scan)
|
||||
is.Equal(score1, uint64(6440))
|
||||
is.Equal(score2, uint64(5905))
|
||||
r, err := run(scan)
|
||||
is.NoErr(err)
|
||||
is.Equal(r.valuePT1, uint64(6440))
|
||||
is.Equal(r.valuePT2, uint64(5905))
|
||||
}
|
||||
|
||||
func TestSolution(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(input))
|
||||
|
||||
score1, score2 := run(scan)
|
||||
t.Log("score1", score1)
|
||||
is.Equal(score1, uint64(248559379))
|
||||
r, err := run(scan)
|
||||
is.NoErr(err)
|
||||
t.Log("score1", r.valuePT1)
|
||||
is.Equal(r.valuePT1, uint64(248559379))
|
||||
|
||||
t.Log("score2", score2)
|
||||
is.Equal(score2, uint64(249631254))
|
||||
t.Log("score2", r.valuePT2)
|
||||
is.Equal(r.valuePT2, uint64(249631254))
|
||||
}
|
||||
|
|
|
@ -28,11 +28,6 @@ func run(scan *bufio.Scanner) (*result, error) {
|
|||
text := scan.Text()
|
||||
m.readLine(text)
|
||||
}
|
||||
// solution9 := m.expand(9).sumPaths()
|
||||
// fmt.Println(solution9)
|
||||
|
||||
// solution99 := m.expand(99).sumPaths()
|
||||
// fmt.Println(solution99)
|
||||
|
||||
return &result{
|
||||
valuePT1: m.expand(1).sumPaths(),
|
||||
|
@ -69,8 +64,8 @@ func (m *Map) String() string {
|
|||
n = n.Next()
|
||||
}
|
||||
|
||||
for row:=0; row<m.rows; row++ {
|
||||
for col:=0; col<m.cols; col++ {
|
||||
for row := 0; row < m.rows; row++ {
|
||||
for col := 0; col < m.cols; col++ {
|
||||
if n := m.getRC(row, col); n != nil {
|
||||
buf.WriteRune('#')
|
||||
} else {
|
||||
|
@ -146,11 +141,11 @@ func (m *Map) expand(rate int) *Map {
|
|||
for col := 0; col < m.cols; col++ {
|
||||
if empty, ok := m.emptyCols[col]; ok && empty {
|
||||
offsetC += rate
|
||||
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if n := m.getRC(row, col); n!= nil {
|
||||
if n := m.getRC(row, col); n != nil {
|
||||
newM.Add('#', fromXY(offsetC+col, offsetR+row, newM.cols))
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +153,7 @@ func (m *Map) expand(rate int) *Map {
|
|||
|
||||
return newM
|
||||
}
|
||||
func(m *Map) sumPaths() int {
|
||||
func (m *Map) sumPaths() int {
|
||||
var positions []int
|
||||
|
||||
n := m.Head()
|
||||
|
@ -170,21 +165,22 @@ func(m *Map) sumPaths() int {
|
|||
var paths []int
|
||||
|
||||
for i := 0; i < len(positions); i++ {
|
||||
p:= positions[i]
|
||||
p := positions[i]
|
||||
pXY := toXY(p, m.cols)
|
||||
|
||||
|
||||
for j := i; j < len(positions); j++ {
|
||||
c := positions[j]
|
||||
if c == p { continue }
|
||||
if c == p {
|
||||
continue
|
||||
}
|
||||
|
||||
cXY := toXY(c, m.cols)
|
||||
cXY := toXY(c, m.cols)
|
||||
|
||||
path := abs(cXY[0]-pXY[0])+abs(cXY[1]-pXY[1])
|
||||
paths = append(paths, path)
|
||||
path := aoc.ABS(cXY[0]-pXY[0]) + aoc.ABS(cXY[1]-pXY[1])
|
||||
paths = append(paths, path)
|
||||
}
|
||||
|
||||
}
|
||||
return sum(paths...)
|
||||
return aoc.Sum(paths...)
|
||||
}
|
||||
|
||||
func all(m map[int]bool) []int {
|
||||
|
@ -198,17 +194,4 @@ func all(m map[int]bool) []int {
|
|||
return lis
|
||||
}
|
||||
func fromXY(x, y, w int) int { return y*w + x }
|
||||
func toXY(i, w int) []int { return []int{i % w, i / w} }
|
||||
func abs(i int) int {
|
||||
if i < 0 {
|
||||
return -i
|
||||
}
|
||||
return i
|
||||
}
|
||||
func sum(arr ...int) int {
|
||||
acc :=0
|
||||
for _, a := range arr {
|
||||
acc += a
|
||||
}
|
||||
return acc
|
||||
}
|
||||
func toXY(i, w int) [2]int { return [2]int{i % w, i / w} }
|
||||
|
|
61
tools.go
61
tools.go
|
@ -183,7 +183,7 @@ func (l *List[T]) add(a *Node[T]) {
|
|||
func (l *List[T]) Get(pos int) *Node[T] {
|
||||
return l.p[pos]
|
||||
}
|
||||
func(l *List[T]) GetN(pos ...int) []*Node[T] {
|
||||
func (l *List[T]) GetN(pos ...int) []*Node[T] {
|
||||
lis := make([]*Node[T], len(pos))
|
||||
for i, p := range pos {
|
||||
lis[i] = l.p[p]
|
||||
|
@ -192,4 +192,61 @@ func(l *List[T]) GetN(pos ...int) []*Node[T] {
|
|||
}
|
||||
func (l *List[T]) Head() *Node[T] {
|
||||
return l.head
|
||||
}
|
||||
}
|
||||
|
||||
func SliceMap[T, U any](fn func(T) U, in ...T) []U {
|
||||
lis := make([]U, len(in))
|
||||
for i := range lis {
|
||||
lis[i] = fn(in[i])
|
||||
}
|
||||
return lis
|
||||
}
|
||||
func SliceIMap[T, U any](fn func(int, T) U, in ...T) []U {
|
||||
lis := make([]U, len(in))
|
||||
for i := range lis {
|
||||
lis[i] = fn(i, in[i])
|
||||
}
|
||||
return lis
|
||||
}
|
||||
|
||||
func Atoi(s string) int {
|
||||
i, _ := strconv.Atoi(s)
|
||||
return i
|
||||
}
|
||||
|
||||
func Repeat(s string, i int) []string {
|
||||
lis := make([]string, i)
|
||||
for i := range lis {
|
||||
lis[i] = s
|
||||
}
|
||||
return lis
|
||||
}
|
||||
|
||||
func Sum[T integer](arr ...T) T {
|
||||
var acc T
|
||||
for _, a := range arr {
|
||||
acc += a
|
||||
}
|
||||
return acc
|
||||
}
|
||||
func SumFunc[T any,U integer](fn func(T) U, input ...T) U {
|
||||
return Sum(SliceMap(fn, input...)...)
|
||||
}
|
||||
func SumIFunc[T any,U integer](fn func(int, T) U, input ...T) U {
|
||||
return Sum(SliceIMap(fn, input...)...)
|
||||
}
|
||||
|
||||
func Power2(n int) int {
|
||||
p := 2
|
||||
for ; n > 1; n-- {
|
||||
p *= 2
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func ABS(i int) int {
|
||||
if i < 0 {
|
||||
return -i
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user