diff --git a/2024/05/5.md b/2024/05/5.md new file mode 100644 index 0000000..cf9d3f4 --- /dev/null +++ b/2024/05/5.md @@ -0,0 +1,160 @@ +## \-\-- Day 5: Print Queue \-\-- + +Satisfied with their search on Ceres, the squadron of scholars suggests +subsequently scanning the +stationery +stacks of sub-basement 17. + +The North Pole printing department is busier than ever this close to +Christmas, and while The Historians continue their search of this +historically significant facility, an Elf operating a [very familiar +printer](/2017/day/1) beckons you over. + +The Elf must recognize you, because they waste no time explaining that +the new *sleigh launch safety manual* updates won\'t print correctly. +Failure to update the safety manuals would be dire indeed, so you offer +your services. + +Safety protocols clearly indicate that new pages for the safety manuals +must be printed in a *very specific order*. The notation `X|Y` means +that if both page number `X` and page number `Y` are to be produced as +part of an update, page number `X` *must* be printed at some point +before page number `Y`. + +The Elf has for you both the *page ordering rules* and the *pages to +produce in each update* (your puzzle input), but can\'t figure out +whether each update has the pages in the right order. + +For example: + + 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 + +The first section specifies the *page ordering rules*, one per line. The +first rule, `47|53`, means that if an update includes both page number +47 and page number 53, then page number 47 *must* be printed at some +point before page number 53. (47 doesn\'t necessarily need to be +*immediately* before 53; other pages are allowed to be between them.) + +The second section specifies the page numbers of each *update*. Because +most safety manuals are different, the pages needed in the updates are +different too. The first update, `75,47,61,53,29`, means that the update +consists of page numbers 75, 47, 61, 53, and 29. + +To get the printers going as soon as possible, start by identifying +*which updates are already in the right order*. + +In the above example, the first update (`75,47,61,53,29`) is in the +right order: + +- `75` is correctly first because there are rules that put each other + page after it: `75|47`, `75|61`, `75|53`, and `75|29`. +- `47` is correctly second because 75 must be before it (`75|47`) and + every other page must be after it according to `47|61`, `47|53`, and + `47|29`. +- `61` is correctly in the middle because 75 and 47 are before it + (`75|61` and `47|61`) and 53 and 29 are after it (`61|53` and + `61|29`). +- `53` is correctly fourth because it is before page number 29 + (`53|29`). +- `29` is the only page left and so is correctly last. + +Because the first update does not include some page numbers, the +ordering rules involving those missing page numbers are ignored. + +The second and third updates are also in the correct order according to +the rules. Like the first update, they also do not include every page +number, and so only some of the ordering rules apply - within each +update, the ordering rules that involve missing page numbers are not +used. + +The fourth update, `75,97,47,61,53`, is *not* in the correct order: it +would print 75 before 97, which violates the rule `97|75`. + +The fifth update, `61,13,29`, is also *not* in the correct order, since +it breaks the rule `29|13`. + +The last update, `97,13,75,29,47`, is *not* in the correct order due to +breaking several rules. + +For some reason, the Elves also need to know the *middle page number* of +each update being printed. Because you are currently only printing the +correctly-ordered updates, you will need to find the middle page number +of each correctly-ordered update. In the above example, the +correctly-ordered updates are: + + 75,47,61,53,29 + 97,61,53,29,13 + 75,29,13 + +These have middle page numbers of `61`, `53`, and `29` respectively. +Adding these page numbers together gives `143`. + +Of course, you\'ll need to be careful: the actual list of *page ordering +rules* is bigger and more complicated than the above example. + +Determine which updates are already in the correct order. *What do you +get if you add up the middle page number from those correctly-ordered +updates?* + +Your puzzle answer was `7198`. + +## \-\-- Part Two \-\-- {#part2} + +While the Elves get to work printing the correctly-ordered updates, you +have a little time to fix the rest of them. + +For each of the *incorrectly-ordered updates*, use the page ordering +rules to put the page numbers in the right order. For the above example, +here are the three incorrectly-ordered updates and their correct +orderings: + +- `75,97,47,61,53` becomes `97,75,47,61,53`. +- `61,13,29` becomes `61,29,13`. +- `97,13,75,29,47` becomes `97,75,47,29,13`. + +After taking *only the incorrectly-ordered updates* and ordering them +correctly, their middle page numbers are `47`, `29`, and `47`. Adding +these together produces `123`. + +Find the updates which are not in the correct order. *What do you get if +you add up the middle page numbers after correctly ordering just those +updates?* + +Your puzzle answer was `4230`. + +Both parts of this puzzle are complete! They provide two gold stars: +\*\* + +At this point, you should [return to your Advent calendar](/2024) and +try another puzzle. + +If you still want to see it, you can [get your puzzle +input](5/input). + diff --git a/2024/05/solution.py b/2024/05/solution.py new file mode 100644 index 0000000..5874ee8 --- /dev/null +++ b/2024/05/solution.py @@ -0,0 +1,123 @@ +#!/bin/python3 +import sys,re +from pprint import pprint +sys.path.insert(0, '../../') +from fred import list2int,get_re,nprint,lprint,swap + +input_f = 'input' + +part = 2 + +def loadData(input_f): + numbers = [] + pages = [] + + with open(input_f) as file: + for line in file: + if '|' in line: + numbers.append(list2int(line.rstrip().split('|'))) + elif ',' in line: + pages.append(list2int(line.rstrip().split(','))) + else: + continue + + return numbers,pages + +######################################### +# # +# Part 1 # +# # +######################################### + +def getMiddle(line:list): + return line[int(len(line)/2)] + +if part == 1: + + def checkPages(line:list,numbers:list): + #print(line) + good = True + for ldx,l in enumerate(line): + for n in numbers: + if n[0] == l: + if n[1] in line and n[1] in line[:(ldx)]: + good = False + #print(n) + #print(ldx,l) + #print(n[1], line) + #print(n[1], line[:(ldx)]) + #input() + #print(good) + #input() + if good: + return line + else: + return None + + numbers = [] + pages = [] + numbers,pages = loadData(input_f) + good = [] + result = 0 + + for lineIdx,line in enumerate(pages): + t = checkPages(line,numbers) + if t is not None: + good.append(t) + + #nprint(good) + + # if line not in good: + # good.append(line) + + for i in good: + result+=getMiddle(i) + + print(result) + +######################################### +# # +# Part 2 # +# # +######################################### +if part == 2: + + def checkPages(line:list,numbers:list): + good = True + ldx = 0 + + while ldx < len(line): + for n in numbers: + if n[0] == line[ldx]: + if n[1] in line and n[1] in line[:(ldx)]: + good = False + ldx+=1 + + return line if not good else None + + def swapBad(numbers,pages): + for _ in range(len(pages)): + for a,b in numbers: + if a in pages and b in pages: + ia = pages.index(a) + ib = pages.index(b) + if ia > ib: + pages = swap(ia,ib,pages[:]) + return pages + + numbers = [] + pages = [] + numbers,pages = loadData(input_f) + bad = [] + result = 0 + + for lineIdx,line in enumerate(pages): + t = checkPages(line,numbers) + if t is not None: + bad.append(swapBad(numbers,t)) + + #print(bad) + for i in bad: + result+=getMiddle(i) + + print(result) \ No newline at end of file diff --git a/2024/05/test2 b/2024/05/test2 new file mode 100644 index 0000000..0a78cab --- /dev/null +++ b/2024/05/test2 @@ -0,0 +1,23 @@ +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,97,47,61,53 diff --git a/README.md b/README.md index b56766e..7c46dc5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ .--'~ ,* ~ | | >o< \_\_\|_/__/ | 2 ** .---': ~ '(~), ~| | >@>O< o-_/.()__------| 3 ** |@..@'. ~ " ' ~ | |>O>o<@< \____ .'| 4 ** - + |_.~._@'.. ~ ~ *| | _| |_ ..\_\_ ..'* | 5 ** ## 2023 diff --git a/__pycache__/fred.cpython-311.pyc b/__pycache__/fred.cpython-311.pyc index 067a3b1..1512d8f 100644 Binary files a/__pycache__/fred.cpython-311.pyc and b/__pycache__/fred.cpython-311.pyc differ diff --git a/fred.py b/fred.py index 4658d0d..79a34b5 100644 --- a/fred.py +++ b/fred.py @@ -12,6 +12,25 @@ def toGrid(input,parser=None): grid.append(list(line.rstrip())) return grid +def swap(a:int,b:int,lst:list): + """ + Swaps two numbers in a list based on their indices. + + Parameters: + lst (list): The list of numbers. + index1 (int): The index of the first number. + index2 (int): The index of the second number. + + Returns: + list: The list after swapping the two numbers. + """ + + if a < 0 or b < 0 or a >= len(lst) or b >= len(lst): + raise IndexError("Index out of range.") + + lst[a], lst[b] = lst[b], lst[a] + return lst + def addTuples(x:tuple,y:tuple): return (x[0]+y[0],x[1]+y[1])