diff --git a/2024/05/main.go b/2024/05/main.go new file mode 100644 index 0000000..124d948 --- /dev/null +++ b/2024/05/main.go @@ -0,0 +1,110 @@ +package main + +import ( + "fmt" + "sort" + "strings" + + "aoc/helper" +) + +type rules map[[2]int]struct{} +type updates []update +type update []int + +func main() { + order_rules, page_updates := getOrdersAndUpdate() + + // part 1 + sum := 0 + for _, update := range page_updates { + if update.validateRules(order_rules) { + sum += update.getMiddleNumber() + } + } + fmt.Printf("Summed updates: %d\n", sum) + + // part 2 + sum = 0 + for _, update := range page_updates { + if update.validateRules(order_rules) { + continue + } + + update.reorderByRules(order_rules) + if update.validateRules(order_rules) { + sum += update.getMiddleNumber() + } + } + fmt.Printf("Sum fixed updates: %d\n", sum) +} + +func (u update) reorderByRules(r rules) update { + sort.Slice( + u, + func(i, j int) bool { + pair := [2]int{u[i], u[j]} + if _, exists := r[pair]; exists { + return true + } + pair = [2]int{u[j], u[i]} + if _, exists := r[pair]; exists { + return false + } + return false + }, + ) + return u +} + +func (u update) validateRules(r rules) bool { + for i := 0; i < len(u)-1; i++ { + // check if a rule exists for current page pair (this + next) + pair := [2]int{u[i+1], u[i]} + if _, exists := r[pair]; exists { + return false + } + } + return true +} + +func (u update) getMiddleNumber() int { + return u[len(u)/2] +} + +func getOrdersAndUpdate() (rules, updates) { + data := helper.GetLines() + + // parse rules + rules := rules{} + for data.Scan() { + line := data.Text() + + if len(line) <= 1 { + // empty line, leave the rest for the update parser + break + } + + parts := strings.Split(line, "|") + page := helper.ToInt(parts[0]) + after := helper.ToInt(parts[1]) + + rules[[2]int{page, after}] = struct{}{} + } + + // parse updates + updates := updates{} + for data.Scan() { + line := data.Text() + parts := strings.Split(line, ",") + + update := update{} + for _, part := range parts { + update = append(update, helper.ToInt(part)) + } + + updates = append(updates, update) + } + + return rules, updates +} diff --git a/helper/input.go b/helper/input.go index e969b4b..da98bab 100644 --- a/helper/input.go +++ b/helper/input.go @@ -11,7 +11,7 @@ import ( const INPUT_FILE = "input" -func getLines() *bufio.Scanner { +func GetLines() *bufio.Scanner { wd, err := os.Getwd() filePath := filepath.Join(wd, INPUT_FILE) @@ -24,7 +24,7 @@ func getLines() *bufio.Scanner { } func ReadLinesTwoIntSlices() (list_a []int, list_b []int) { - scanner := getLines() + scanner := GetLines() for scanner.Scan() { parts := strings.Fields(scanner.Text()) @@ -39,7 +39,7 @@ func ReadLinesTwoIntSlices() (list_a []int, list_b []int) { } func ReadLinesToIntSlices() (lines [][]int) { - scanner := getLines() + scanner := GetLines() for scanner.Scan() { string_line := strings.Fields(scanner.Text()) int_line := make([]int, len(string_line)) @@ -53,7 +53,7 @@ func ReadLinesToIntSlices() (lines [][]int) { } func ReadLinesToStringSlices() (lines []string) { - scanner := getLines() + scanner := GetLines() for scanner.Scan() { lines = append(lines, scanner.Text()) } @@ -62,7 +62,7 @@ func ReadLinesToStringSlices() (lines []string) { } func ReadLinesToString() (line string) { - scanner := getLines() + scanner := GetLines() for scanner.Scan() { line += scanner.Text() }