Seite 23 von 24
Re: Advent of Code
Verfasst: Dienstag 3. Dezember 2024, 12:12
von __blackjack__
@Kebap: Muss ich gleich mal prüfen ob "\d+" tatsächlich funktioniert mit meinen Eingabedaten. Die Aufgabe war da ein bisschen spezifischer → "\d{1,3}". Das heisst "mul(42,4711)" wäre illegal, würde von "\d+" aber erfasst.
Re: Advent of Code
Verfasst: Dienstag 3. Dezember 2024, 12:15
von Kebap
@__blackjack__: Stimmt, das hatte ich wohl überlesen oder wieder vergessen. Jedenfalls hat es mein Ergebnis nicht beeinflusst.
Ich war hingegen an zwei anderen Stellen gestolpert:
- Der Status muss am Ende nicht "aktiviert" sein, also müssen ggf. mul-Befehle am Ende ignoriert werden. OK, leicht zu beheben. Randfälle sind ja Klassiker.
- Der Regex sucht nicht über Zeilenenden (also im gewissen Sinne auch "über einen Rand") hinweg. Also sowas wie hier hatte ich zuerst falsch behandelt:
don't()_blablabla
jippie_don't()_foobar_do()
Bei mir wurde zunächst nur foobar ignoriert. Wobei tatsächlich die kompletten zwei Zeilen ignoriert gehören! Der Workaround war zuerst \n zu löschen.
Re: Advent of Code
Verfasst: Dienstag 3. Dezember 2024, 21:18
von Dennis89
Danke für euren Input für Tag 2.
Bis jetzt habe ich noch kein Code geschrieben, der mir gefällt

Heute wurde es auch nicht besser, dafür war ich sehr schnell fertig. (Was gut war, weil ich leider nicht viel Zeit dazu hatte)
Code: Alles auswählen
#!/usr/bin/env python
import re
from pathlib import Path
INPUT_FILE = Path(__file__).parent / "input03.txt"
PUZZLE_INPUT = """\
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))
""".splitlines()
EXPRESSION = re.compile(r"mul\(\d*,\d*\)|don't\(\)|do\(\)")
def parse_input(lines):
expressions = []
for line in lines:
expressions.extend(re.findall(EXPRESSION, line))
return expressions
def decode_expression(expression):
if expression.startswith("mul"):
return map(int, re.findall(r"\d*,\d*", expression)[0].split(","))
return 0, 0
def get_mul(mul):
x, y = decode_expression(mul)
return x * y
def run_mul_expressions(expressions):
return sum(get_mul(expression) for expression in expressions)
def run_and_enable_mul_expressions(expressions):
run = True
multiples = []
for expression in expressions:
if expression == "don't()":
run = False
elif expression == "do()":
run = True
elif run:
multiples.append(get_mul(expression))
return sum(multiples)
def main():
puzzle_input = PUZZLE_INPUT
puzzle_input = INPUT_FILE.read_text(encoding="UTF-8").splitlines()
expressions = parse_input(puzzle_input)
print(run_mul_expressions(expressions))
print(run_and_enable_mul_expressions(expressions))
if __name__ == "__main__":
main()
Ach und Tag 2 noch (fand das vorgeschlagene `skip_index`) schöner wie mein slicing:
Code: Alles auswählen
#!/usr/bin/env python
from itertools import pairwise
from pathlib import Path
INPUT_FILE = Path(__file__).parent / "input02.txt"
PUZZLE_INPUT = """\
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
""".splitlines()
def is_safe(report):
return (
all(1 <= x - y <= 3 for x, y in pairwise(report))
or all(1 <= y - x <= 3 for x, y in pairwise(report))
)
def get_safe_reports(reports):
return sum(is_safe(report) for report in reports)
def skip_index(iterable, index):
for i, value in enumerate(iterable):
if i != index:
yield value
def get_tolerated_safe_reports(reports):
safe_reports = 0
for report in reports:
if is_safe(report):
safe_reports += 1
else:
for index in range(len(report)):
if is_safe(list(skip_index(report, index))):
safe_reports += 1
break
return safe_reports
def main():
# puzzle_input = PUZZLE_INPUT
puzzle_input = INPUT_FILE.read_text(encoding="UTF-8").splitlines()
reports = list(map(lambda x: list(map(int, x.split())), puzzle_input))
print(get_safe_reports(reports))
print(get_tolerated_safe_reports(reports))
if __name__ == "__main__":
main()
Grüße
Dennis
Re: Advent of Code
Verfasst: Dienstag 3. Dezember 2024, 22:49
von __blackjack__
Hm, ich denke die lassen langsam nach. Früher hätten sie sichergestellt das weder "\d+" und schon gar nicht "\d*" funktioniert hätte.

Re: Advent of Code
Verfasst: Dienstag 3. Dezember 2024, 23:22
von narpfel
Wenn man was parsen muss, ist Prolog immer eine gute Wahl:
Code: Alles auswählen
#!/usr/bin/env -S swipl -g main -t halt
:- use_module(library(dcg/basics)).
:- use_module(library(pure_input)).
one_to_three_digit_integer(Int) --> integer(Int), { 0 =< Int, Int < 1000 }.
mul(Product) -->
"mul(", one_to_three_digit_integer(Lhs), ",", one_to_three_digit_integer(Rhs), ")",
{ Product is Lhs * Rhs }.
conditional_mul(Value) --> mul(Value).
conditional_mul(0) --> "don't()", string(_), "do()".
multiplications(Mul, Result) -->
string(_), call(Mul, Product), multiplications(Mul, Rest),
{ Result is Rest + Product }.
multiplications(_, 0) --> string(_), eos.
main :-
phrase_from_file(multiplications(mul, Part1), input),
write(Part1), nl,
phrase_from_file(multiplications(conditional_mul, Part2), input),
write(Part2), nl.
Interessanterweise brauche ich für meinen Input den Test auf höchstens drei Ziffern auch nicht. Scheint also gewollt zu sein, dass das keine „richtige“ Anforderung ist.
Re: Advent of Code
Verfasst: Dienstag 3. Dezember 2024, 23:50
von __blackjack__
Vielleicht weil es erst der dritte Tag ist.

Re: Advent of Code
Verfasst: Mittwoch 4. Dezember 2024, 07:24
von Dennis89
Oh:
it specifies that the previous character can be matched zero or more times, instead of exactly once.
Eigentlich wollte ich `+`weil ich wohl die Aufgabenstellung nicht ordentlich gelesen habe

Re: Advent of Code
Verfasst: Mittwoch 4. Dezember 2024, 09:58
von __blackjack__
@Kebap: Zeilenenden löschen ist aber auch gefährlich, denn das würde beispielsweise aus einem "d\no()" ein "do()" machen was es gar nicht geben sollte.
Re: Advent of Code
Verfasst: Mittwoch 4. Dezember 2024, 19:41
von nezzcarth
Keine Ahnung, ob ich etwas falsch gemacht habe, aber Teil 1 und Teil 2 kamen mir heute fast wie zwei separate Aufgaben vor und der zweiter leichter als der erste.
Re: Advent of Code
Verfasst: Mittwoch 4. Dezember 2024, 21:00
von __blackjack__
Also ich habe eine Funktion die beide Teile benutzen, die die Koordinaten des jeweiligen Startbuchstabens liefert.

Re: Advent of Code
Verfasst: Donnerstag 5. Dezember 2024, 13:41
von __blackjack__
@nezzcarth: Wenn ich so drüber nachdenke kann man da aber *eine* Funktion schreiben, die das Suchmuster als Datenstruktur bekommt.
@all: Heute war soweit ich das sehe, die erste schwierigere Aufgabe, also Aufgabenteil 2. Also zumindest sofern man nicht auf den Namen des Algorithmus kommt, den man da benutzen kann. Und es ist natürlich dann auch praktisch, dass es den Algorithmus schon fertig in der Standardbibliothek gibt.

Re: Advent of Code
Verfasst: Donnerstag 5. Dezember 2024, 16:13
von Kebap
@__blackjack__: Da hast du tatsächlich auch wieder Recht..!
__blackjack__ hat geschrieben: Mittwoch 4. Dezember 2024, 09:58
@Kebap: Zeilenenden löschen ist aber auch gefährlich, denn das würde beispielsweise aus einem "d\no()" ein "do()" machen was es gar nicht geben sollte.
Re: Advent of Code
Verfasst: Donnerstag 5. Dezember 2024, 18:09
von Dennis89
Ich war gestern den ganzen Tag unterwegs und wie ich heute feststellen musste, habe ich nur ein dummes Rätsel verpasst. Ich will die Rätsel immer nutzen um an mir zu arbeiten, aber hier fällt mir nur ein, das ich mir merke wo in welcher Reihe und welcher Position ein "X" steht und dann muss ich gefühlt über 100 verschachtelte Schleifen den gefunden Index, wie auch die Reihe in alle Richtungen erhöhen und schauen ob irgendwie das Wort zusammen kommt.
Ich erinnere mich an letztes Jahr, da musste man Symbole suchen, aber wenigstens nur im Umkreis von einem Index-Wert und das war bei mir schon doof unleserlich. Ich wette, falls __blackjack__ das in Python gelöst hat, gibt es wieder "schlaue" Map-Objekte und dann geht das wie von alleine. Aber ich komm auf sowas einfach nicht.
Re: Advent of Code
Verfasst: Donnerstag 5. Dezember 2024, 18:15
von nezzcarth
__blackjack__ hat geschrieben: Donnerstag 5. Dezember 2024, 13:41
Und es ist natürlich dann auch praktisch, dass es den Algorithmus schon fertig in der Standardbibliothek gibt.
Falls wir an dasselbe denken, war zumindest mein Input so aufgebaut, dass er mit dem Ding aus der Standardbibliothek problemlos durchlief, beim eigentlichen Input aber Probleme machte.

Re: Advent of Code
Verfasst: Donnerstag 5. Dezember 2024, 18:27
von narpfel
Ich finde, die heutige Aufgabe war geradezu prädestiniert dazu, sie in einem Basheinzeiler zu lösen:
Code: Alles auswählen
for eq in "==" "!="; do grep , input | tr ',' '|' | xargs -I '{}' bash -c 'l=$(grep -E '"'"'({})\|({})'"'"' input | tr '"'"'|'"'"' '"'"' '"'"' | tsort | grep -E '"'"'{}'"'"'); n=$(echo "$l" | wc -l); if [[ $(echo '"'"'{}'"'"' | tr '"'"'|'"'"' '"'"','"'"'), '$eq' $(echo "$l" | tr '"'"'\n'"'"' '"'"','"'"') ]]; then echo "$l" | head -n $(($n / 2 + 1)) | tail -n1; fi' | sed -E 's/\s+/+/g' | paste -sd+ | bc; done
Das ist nur 100x langsamer als meine Python-Lösung.
__blackjack__ hat geschrieben: Donnerstag 5. Dezember 2024, 13:41
Und es ist natürlich dann auch praktisch, dass es den Algorithmus schon fertig in der Standardbibliothek gibt.
Meinst du (Achtung, Spoiler!)
das hier? Das habe ich nicht benutzt, meine Lösung ist einfacher und benutzt nur Builtins und eine wenig benutzte, aber bei AoC immer wieder erstaunlich hilfreiche Funktion aus `functools`. Das funktioniert, weil die Inputdaten eine totale Ordnung bilden und jedes Paar aus den einzelnen Updates immer in genau einer der beiden möglichen Reihenfolge vorkommt.
Re: Advent of Code
Verfasst: Donnerstag 5. Dezember 2024, 18:38
von narpfel
Dennis89 hat geschrieben: Donnerstag 5. Dezember 2024, 18:09
Ich war gestern den ganzen Tag unterwegs und wie ich heute feststellen musste, habe ich nur ein dummes Rätsel verpasst. Ich will die Rätsel immer nutzen um an mir zu arbeiten, aber hier fällt mir nur ein, das ich mir merke wo in welcher Reihe und welcher Position ein "X" steht und dann muss ich gefühlt über 100 verschachtelte Schleifen den gefunden Index, wie auch die Reihe in alle Richtungen erhöhen und schauen ob irgendwie das Wort zusammen kommt.
Es gibt auch einen anderen Lösungsansatz, der nicht unbedingt einfacher, aber vielleicht interessanter ist: In einem String kann man `XMAS` einfach mit `str.count` zählen. Wenn man den String drehen könnte, würde man `XMAS` auch diagonal/senkrecht/rückwärts einfach mit `str.count` suchen können...

Re: Advent of Code
Verfasst: Donnerstag 5. Dezember 2024, 18:46
von nezzcarth
narpfel hat geschrieben: Donnerstag 5. Dezember 2024, 18:27
Meinst du (Achtung, Spoiler!)
das hier? Das habe ich nicht benutzt, meine Lösung ist einfacher
Der Input ist mutwillig so gestaltet, dass das im Spoiler Angesprochene explizit nicht so ohne Weiteres funktioniert.
Re: Advent of Code
Verfasst: Donnerstag 5. Dezember 2024, 19:10
von narpfel
nezzcarth hat geschrieben: Donnerstag 5. Dezember 2024, 18:46
Der Input ist mutwillig so gestaltet, dass das im Spoiler Angesprochene explizit nicht so ohne Weiteres funktioniert.
Das „nicht ohne Weiteres“ ist dann aber ein relativ einfacher Schritt? Alle Paare ignorieren, bei denen nicht beide Zahlen in der betrachteten Update-Zeile vorkommen? So hab ich es zumindest in der gezeigten Bash-Lösung gemacht.
Re: Advent of Code
Verfasst: Donnerstag 5. Dezember 2024, 19:16
von nezzcarth
Genau

Re: Advent of Code
Verfasst: Donnerstag 5. Dezember 2024, 22:50
von __blackjack__
@nezzcarth: Wir denken an das selbe. Der Hinweis Regeln die sich auf Seitenzahlen beziehen, die nicht im jeweiligen Update vorkommen, zu ignorieren, steht soweit ich mich erinnere ja sogar in der Aufgabe. Ich bin da aber auch erst einmal in die Ausnahme wegen einem Kreis gerannt.
@Dennis89: Eine Schleife um die ganzen Koordinaten des Startbuchstabens "X" zu finden, und eine Schleife über die 8 möglichen Richtungen, und dann eine Schleife die diese Richtung absucht. Das sind doch bloss 3 Schleifen. Eine davon ist in einer Funktion ausgelagert und die kann man im zweiten Aufgabenteil benutzen um die ganzen Koordinaten des Startbuchstabens dort zu finden.