day2
This commit is contained in:
105
2024/go/day02/day02.go
Normal file
105
2024/go/day02/day02.go
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
package day02
|
||||||
|
|
||||||
|
import (
|
||||||
|
"adventofcode2024/utils"
|
||||||
|
_ "adventofcode2024/utils"
|
||||||
|
_ "adventofcode2024/utils/grid2d"
|
||||||
|
_ "adventofcode2024/utils/inputs"
|
||||||
|
_ "errors"
|
||||||
|
_ "fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Dir int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Up Dir = iota
|
||||||
|
Down
|
||||||
|
Safe
|
||||||
|
Unsafe
|
||||||
|
)
|
||||||
|
|
||||||
|
// Implement the Stringer interface
|
||||||
|
func (d Dir) String() string {
|
||||||
|
switch d {
|
||||||
|
case Up:
|
||||||
|
return "Up"
|
||||||
|
case Down:
|
||||||
|
return "Down"
|
||||||
|
case Safe:
|
||||||
|
return "Safe"
|
||||||
|
case Unsafe:
|
||||||
|
return "Unsafe"
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Part1(input string) int {
|
||||||
|
count := 0
|
||||||
|
lines := strings.Split(input, "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
if isSafe(fields) {count++}
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
func Part2(input string) int {
|
||||||
|
count := 0
|
||||||
|
lines := strings.Split(input, "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
if isSafe(fields) {
|
||||||
|
count++
|
||||||
|
} else {
|
||||||
|
for i := 0; i < len(fields); i++ {
|
||||||
|
// Create a new slice excluding the current item
|
||||||
|
newFields := applyDampner(fields, i)
|
||||||
|
if isSafe(newFields) {
|
||||||
|
count++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSafe(fields []string) bool {
|
||||||
|
Dir := getDir(utils.MustAtoi(fields[0]), utils.MustAtoi(fields[1]))
|
||||||
|
if Dir == Unsafe {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for x := 2; x < len(fields); x++ {
|
||||||
|
NextDir := getDir(utils.MustAtoi(fields[x-1]), utils.MustAtoi(fields[x]))
|
||||||
|
if NextDir == Unsafe {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if NextDir != Dir {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDir(a int, b int) Dir {
|
||||||
|
var dir Dir
|
||||||
|
diff := b - a
|
||||||
|
if diff > 0 && utils.Abs(diff) < 4 {
|
||||||
|
dir = Up
|
||||||
|
} else if diff < 0 && utils.Abs(diff) < 4 {
|
||||||
|
dir = Down
|
||||||
|
} else {
|
||||||
|
dir = Unsafe
|
||||||
|
}
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyDampner(fields []string, pos int) []string {
|
||||||
|
copy := append([]string{}, fields...)
|
||||||
|
if pos < 0 || pos >= len(copy) {
|
||||||
|
return copy // Return the fields unchanged if pos is invalid
|
||||||
|
}
|
||||||
|
return append(copy[:pos], copy[pos+1:]...)
|
||||||
|
}
|
||||||
29
2024/go/day02/day02_test.go
Normal file
29
2024/go/day02/day02_test.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package day02
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPart1(t *testing.T) {
|
||||||
|
r := Part1(
|
||||||
|
`7 6 4 2 1
|
||||||
|
1 2 7 8 9
|
||||||
|
9 7 6 2 1
|
||||||
|
1 3 2 4 5
|
||||||
|
8 6 4 4 1
|
||||||
|
1 3 6 7 9`)
|
||||||
|
require.Equal(t, 2, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPart2(t *testing.T) {
|
||||||
|
r := Part2(
|
||||||
|
`7 6 4 2 1
|
||||||
|
1 2 7 8 9
|
||||||
|
9 7 6 2 1
|
||||||
|
1 3 2 4 5
|
||||||
|
8 6 4 4 1
|
||||||
|
1 3 6 7 9`)
|
||||||
|
require.Equal(t, 4, r)
|
||||||
|
}
|
||||||
1000
2024/go/day02/input.txt
Normal file
1000
2024/go/day02/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ import (
|
|||||||
// "time"
|
// "time"
|
||||||
"adventofcode2024/utils"
|
"adventofcode2024/utils"
|
||||||
"adventofcode2024/day01"
|
"adventofcode2024/day01"
|
||||||
|
"adventofcode2024/day02"
|
||||||
)
|
)
|
||||||
// Usage: go run main.go <NN>
|
// Usage: go run main.go <NN>
|
||||||
// assumes input is in day<NN>/input.txt
|
// assumes input is in day<NN>/input.txt
|
||||||
@@ -19,6 +20,9 @@ func main() {
|
|||||||
case 1:
|
case 1:
|
||||||
fmt.Printf("part 1: %d\n", day01.Part1(utils.Readfile(d)))
|
fmt.Printf("part 1: %d\n", day01.Part1(utils.Readfile(d)))
|
||||||
fmt.Printf("part 2: %d\n", day01.Part2(utils.Readfile(d)))
|
fmt.Printf("part 2: %d\n", day01.Part2(utils.Readfile(d)))
|
||||||
|
case 2:
|
||||||
|
fmt.Printf("part 1: %d\n", day02.Part1(utils.Readfile(d)))
|
||||||
|
fmt.Printf("part 2: %d\n", day02.Part2(utils.Readfile(d)))
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("no such day: %d", d))
|
panic(fmt.Errorf("no such day: %d", d))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func ToInts(input string, sep string) []int {
|
|||||||
func ToGrid2D[T any](input, rowSep, colSep string, empty T, conv func(string) T) *grid2d.Grid[T] {
|
func ToGrid2D[T any](input, rowSep, colSep string, empty T, conv func(string) T) *grid2d.Grid[T] {
|
||||||
lines := strings.Split(input, rowSep)
|
lines := strings.Split(input, rowSep)
|
||||||
|
|
||||||
grid := grid2d.NewGrid(len(lines[0]), len(lines), empty)
|
grid := grid2d.NewGrid(len(lines[0]) - strings.Count(lines[0], colSep), len(lines), empty)
|
||||||
for y, line := range lines {
|
for y, line := range lines {
|
||||||
for x, v := range strings.Split(line, colSep) {
|
for x, v := range strings.Split(line, colSep) {
|
||||||
grid.Set(x, y, conv(v))
|
grid.Set(x, y, conv(v))
|
||||||
|
|||||||
Reference in New Issue
Block a user