day5
This commit is contained in:
148
2024/go/day05/day05.go
Normal file
148
2024/go/day05/day05.go
Normal file
@@ -0,0 +1,148 @@
|
||||
package day05
|
||||
|
||||
import (
|
||||
"adventofcode2024/utils"
|
||||
_ "sort"
|
||||
"strings"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func Part1(input string) int {
|
||||
num := 0
|
||||
rules := make(map[int][]int)
|
||||
|
||||
sections := strings.Split(input, "\n\n")
|
||||
rules_str := strings.Split(sections[0], "\n")
|
||||
updates_str := strings.Split(sections[1], "\n")
|
||||
updates := make([][]int, len(updates_str))
|
||||
|
||||
for _, rule := range rules_str {
|
||||
fields := strings.Split(rule, "|")
|
||||
// Convert the fields to integers
|
||||
val1 := utils.MustAtoi(fields[0])
|
||||
val2 := utils.MustAtoi(fields[1])
|
||||
rules[val1] = append(rules[val1], val2)
|
||||
}
|
||||
for i, update := range updates_str {
|
||||
fields := strings.Split(update, ",")
|
||||
for _, field := range fields {
|
||||
updates[i] = append(updates[i], utils.MustAtoi(field))
|
||||
}
|
||||
}
|
||||
for _, update := range updates {
|
||||
good := true
|
||||
reverseSlice(update)
|
||||
fmt.Printf("rules: %v\n", rules)
|
||||
fmt.Printf("update: %v\n", update)
|
||||
for i, page := range update {
|
||||
for _, rule := range rules[page] {
|
||||
if contains(update[i+1:], rule) {
|
||||
good = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if !good {
|
||||
break
|
||||
}
|
||||
}
|
||||
if good {
|
||||
fmt.Printf("good: %v\n", update)
|
||||
num += update[len(update)/2]
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
func Part2(input string) int {
|
||||
num := 0
|
||||
rules := make(map[int][]int)
|
||||
|
||||
sections := strings.Split(input, "\n\n")
|
||||
rules_str := strings.Split(sections[0], "\n")
|
||||
updates_str := strings.Split(sections[1], "\n")
|
||||
updates := make([][]int, len(updates_str))
|
||||
|
||||
for _, rule := range rules_str {
|
||||
fields := strings.Split(rule, "|")
|
||||
// Convert the fields to integers
|
||||
val1 := utils.MustAtoi(fields[0])
|
||||
val2 := utils.MustAtoi(fields[1])
|
||||
rules[val1] = append(rules[val1], val2)
|
||||
}
|
||||
for i, update := range updates_str {
|
||||
fields := strings.Split(update, ",")
|
||||
for _, field := range fields {
|
||||
updates[i] = append(updates[i], utils.MustAtoi(field))
|
||||
}
|
||||
}
|
||||
for _, update := range updates {
|
||||
reverseSlice(update)
|
||||
if !isGood(update, rules) {
|
||||
fmt.Printf("not good: %v\n", update)
|
||||
makeGood(update, rules)
|
||||
fmt.Printf("good: %v\n", update)
|
||||
num += update[len(update)/2]
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
func contains(slice []int, x int) bool {
|
||||
for _, value := range slice {
|
||||
if value == x {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func location(slice []int, x int) int {
|
||||
for i, value := range slice {
|
||||
if value == x {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func reverseSlice(slice []int) {
|
||||
for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 {
|
||||
slice[i], slice[j] = slice[j], slice[i]
|
||||
}
|
||||
}
|
||||
|
||||
func isGood(update []int, rules map[int][]int) bool {
|
||||
good := true
|
||||
for i, page := range update {
|
||||
for _, rule := range rules[page] {
|
||||
if contains(update[i+1:], rule) {
|
||||
good = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if !good {
|
||||
return good
|
||||
}
|
||||
}
|
||||
return good
|
||||
}
|
||||
|
||||
func makeGood(update []int, rules map[int][]int) []int {
|
||||
for i, page := range update {
|
||||
for _, rule := range rules[page] {
|
||||
loc := location(update[i+1:], rule)
|
||||
if loc != -1 {
|
||||
swap(update, loc+i+1, i)
|
||||
makeGood(update, rules)
|
||||
}
|
||||
}
|
||||
}
|
||||
return update
|
||||
}
|
||||
|
||||
func swap(slice []int, i, j int) {
|
||||
if i < 0 || i >= len(slice) || j < 0 || j >= len(slice) {
|
||||
panic("Index out of range")
|
||||
}
|
||||
slice[i], slice[j] = slice[j], slice[i]
|
||||
}
|
||||
71
2024/go/day05/day05_test.go
Normal file
71
2024/go/day05/day05_test.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package day05
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestPart1(t *testing.T) {
|
||||
r := Part1(`47|53
|
||||
97|13
|
||||
97|61
|
||||
97|47
|
||||
75|29
|
||||
61|13
|
||||
75|53
|
||||
29|13
|
||||
97|29
|
||||
53|29
|
||||
61|53
|
||||
97|53
|
||||
61|29
|
||||
47|13
|
||||
75|47
|
||||
97|75
|
||||
47|61
|
||||
75|61
|
||||
47|29
|
||||
75|13
|
||||
53|13
|
||||
|
||||
75,47,61,53,29
|
||||
97,61,53,29,13
|
||||
75,29,13
|
||||
75,97,47,61,53
|
||||
61,13,29
|
||||
97,13,75,29,47`)
|
||||
require.Equal(t, 143, r)
|
||||
}
|
||||
|
||||
func TestPart2(t *testing.T) {
|
||||
r := Part2(`47|53
|
||||
97|13
|
||||
97|61
|
||||
97|47
|
||||
75|29
|
||||
61|13
|
||||
75|53
|
||||
29|13
|
||||
97|29
|
||||
53|29
|
||||
61|53
|
||||
97|53
|
||||
61|29
|
||||
47|13
|
||||
75|47
|
||||
97|75
|
||||
47|61
|
||||
75|61
|
||||
47|29
|
||||
75|13
|
||||
53|13
|
||||
|
||||
75,47,61,53,29
|
||||
97,61,53,29,13
|
||||
75,29,13
|
||||
75,97,47,61,53
|
||||
61,13,29
|
||||
97,13,75,29,47`)
|
||||
require.Equal(t, 123, r)
|
||||
}
|
||||
1362
2024/go/day05/input.txt
Normal file
1362
2024/go/day05/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,7 @@ import (
|
||||
"adventofcode2024/day02"
|
||||
"adventofcode2024/day03"
|
||||
"adventofcode2024/day04"
|
||||
|
||||
"adventofcode2024/day05"
|
||||
)
|
||||
// Usage: go run main.go <NN>
|
||||
// assumes input is in day<NN>/input.txt
|
||||
@@ -32,6 +32,9 @@ func main() {
|
||||
case 4:
|
||||
fmt.Printf("part 1: %d\n", day04.Part1(utils.Readfile(d)))
|
||||
fmt.Printf("part 2: %d\n", day04.Part2(utils.Readfile(d)))
|
||||
case 5:
|
||||
fmt.Printf("part 1: %d\n", day05.Part1(utils.Readfile(d)))
|
||||
fmt.Printf("part 2: %d\n", day05.Part2(utils.Readfile(d)))
|
||||
default:
|
||||
panic(fmt.Errorf("no such day: %d", d))
|
||||
}
|
||||
@@ -39,7 +42,7 @@ func main() {
|
||||
|
||||
// Reads day from os.Args.
|
||||
func day() int {
|
||||
latest := 3
|
||||
latest := 4
|
||||
if len(os.Args) == 1 {
|
||||
return latest
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user