From f4c442bf1ad5b2de3083c08e1595fbae8484a467 Mon Sep 17 00:00:00 2001
From: FrederikBaerentsen <frederik+gitea@baerentsen.net>
Date: Thu, 5 Dec 2024 18:10:12 +0100
Subject: [PATCH] Solved 2024/05 P1+P2

---
 2024/05/5.md                     | 160 +++++++++++++++++++++++++++++++
 2024/05/solution.py              | 123 ++++++++++++++++++++++++
 2024/05/test2                    |  23 +++++
 README.md                        |   2 +-
 __pycache__/fred.cpython-311.pyc | Bin 8434 -> 9260 bytes
 fred.py                          |  19 ++++
 6 files changed, 326 insertions(+), 1 deletion(-)
 create mode 100644 2024/05/5.md
 create mode 100644 2024/05/solution.py
 create mode 100644 2024/05/test2

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 067a3b1b15ecb9fe5032da7ee9e691f687b86528..1512d8f59b79c8c726d7c9c58eb1de473d6f3cde 100644
GIT binary patch
delta 1714
zcmZ`(OKclO7@k>s*N@oiS6;SbvLRBMEww|NhDX$<EfrB4QkRgnAalXVY!VaK4zsor
zz>-5130EKyF@+c?QbDMsv`Bz2lq09!2vUS1iy{ywPE<rlC|vmebzCAOR@(pn{`X^M
z_m2~|PL)6Pdffz`zki&VWg$X-MWOj9yI}ic0BeL1MzbW<;50>9gh?wjB{7>}V|I9D
z!#<-hWyPM7nZr<+(@<vY%muQ8xxpr}7QjxhxtPargYB#r6fI0$At?{@0rj#d^BXD)
z7%ngeSLBqBg+T9Ttv~~;4QP<H0}Zh*)(Kt`3xiiHqmx9Befdp7qC>Ucq<84Cbe&Gs
zZCSH0ZEFq$T!t6r?JXc{qy#g~10uvcP@?y7Ux|oc{9W#ObSGx0L{Tg^M6MO~WGs;q
zElJlwbMwBIl7bb8!GtjBIt44djpq{hmuR>t5|GHh(zJx~5wN0HgTrXHbO(K$5Vr=;
z<YIck)C!AvEmyoaWpGo=<g~Pw&6ovkDs37}%jdMhoRQ&RV3}#d6u-B3lwlQGKRW5d
z+POKS;h&#rCP`SiA;4HVsP$)ZO*c!UfgfblW-=VIG|KJ?IP|{(rZJt*F^nifrwO-J
z<Qbz-<T-QL60oB^4W(xa2G>j&aUqkNwTkYUv{92wu%1^!r?FQpUo2pEJe`|061okJ
z+{o4C1r8I`-ImLfoaeb-w($Uj@gNeo>cqtJf^~8q@VXsK@=ky#nt340<X(h0U6q5E
zip#}Sx_aVmc~!0kKAgVR``+Bux%Xq$*m}?B<`;uEmToP57GICwb$TmlaO}OTzNuE!
zyK3h~IPtwYu&EAgIQs^EZtJWDu3V^2UJG2ku$){zS)s3uR!*+c%cEN@>hjn&)Fh&0
zUs56fcvS4zqjEREUJ;Sw5)X^h^0zc5Jj!|6FQ$~oXjpup^vnCerBB>Z4uJfpa{eLS
z4hmi3R+fIiChn^_sFJmI!}o)3zgToYRP7VT5S4iwXv9y>3HcC!ggET_2onC_x*3dv
zZ0%f^>NeObZxh1ZBM*W4sJQJOfee4S-=)ynTb>6yFioQc2lpU;1j(b~jwdcZ0r0rk
z@oYlo@4Q9lVUTsoBVt_bq~pR+d%*Cz`jr=x=yGF(s2KG<ET00+S@EjxIq=x@EzzgM
z8Gl$#g7%!4_b04`VNvsc9f$9P@L^0K@uP^Xee5P1LB%m7$B~>6)j*g0G{BU&9avEC
zL*%jAK=647jf*$JFEv_}c(1TW#wiyQks)j`GM0>?D{dCbAmh*O!Ds|Ms+xKW@9M4C
zU4IM5M0b>TSkQ$rXOQ3^x(l|w9^FUV#YS|nWdilP*F)_}%lPwpp;qWxlgd`>b_|h{
zN!^y@m@TQd@iE|aoB6WI{eU>`oLfckw%6rCaUpAPyk{J5l2y8HpUUU6)*az^8#tad
z??Zw|$Q?-VL^vJ*$NlLXd*Kftv0B0JXvcZvVxASV#t6qR3jcxTi{eK2fF7j2%HTZ$
WY&B%DYOBTmOZsbD-R;zl8UF$G-GtBp

delta 1013
zcmXw1&ubGw6yDk0$!3$RNw%A$)iy~}NDcItwAE@#vEq+XYp`gc#G+JZTZ^%cvn{j;
z79{5$9Bjdh6bc?HNX^Yt{{p2T2oXgP&w{-P{&;Va?%~_-eeau@H*enSv0tO>uPiH|
zz-R4UpT8efl<ycEeY8OiH-Ky@Okt#?6zhLdBrML<3Mr~gb2X;B+MLd4MK9{i=h8Wq
z8NhvzGnn7?L(YWQWPyrO46q<zkR@0?<c65#8jwC#p+$>@A#sdF0K+T_7-2SGlr=L4
zTq=u!%Vy+;l55#}-=mU&>L2wv(N}9^O?<WEV%wO>!Zj3b19&PxI?coItC_Qm-CQY`
zT#v^g4vP+dcjyq9!m$JQi1=nZqU_%xj)<94fDg<ek`O!QNtyzKEe^~si2s^Xks2-Y
zg~jEZ%H>&UF&k*69bk%!Cjl^3cLRfj*0hqlD1HPdX&0o9i+pGs)_)1@+F6J>7MD|N
z8f?Tn#S5#Q_M#&8tr6JapS4M#hRtv$(TVO1<_sP}-iL5Xd<b{bVW3@tL_WgK+f6Ov
zXJn?m2dzYw<`Lla25<vcAq<I9v>p5#(YF@voul<@*y5VqM=yYq7f<bJaD28`Q<ot2
zG=TI`Cw=qo@*VE-F%ZuS-qa({KIra;m=6FzU(O(xH8(aNLg6gJIfT4;>9o>upqItI
zQ}!iLbgHLgw+xaM&srb(<t<cxLIm3;$Zav*Hi#v+jTaoW)|)4Pd=dmW5+#mF;3ysG
zk~eg@w&9oD5!ob9NNVDmD+qXzoC%NeCfP|c;#0Cecop?1f-PdHS?U6vs6I|@sq3<I
z9hazuLQX5l8Vb24ei5{q=B;@=f{ZTX^vU7l@+_Pxd0<VyyR=l|I6xdnh2tRbBm%x~
x{pIjoWXm~rjbi~k29V;i0G#pP{^5s9Y^CIm@C69*?Y&X)F4J4JJK{t~-+!S$$e#cJ

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])