Advent of Code
-
- User
- Beiträge: 219
- Registriert: Donnerstag 21. Juli 2011, 07:01
- Wohnort: Stade / Hamburg
- Kontaktdaten:
Day 3: check
Meine Lösungen sind ordentlich und funktionieren, denke ich. Dennoch sind sie sehr einfach. Wenn ich dann die Lösungen von @ThomasL sehe oder die Hinweise für @snafu denke ich immer, warum bin ich nicht darauf gekommen. Die Konzepte sind alle bekannt, aber eben nicht wirklich im "Muskelgedächtnis".
Da ich leider nie als Entwickler in einem Team gearbeitet habe, fehlt mir glaube ich externes Feedback. Pair-Programming und Code-Reviews. Naja, ich werde versuchen hier mehr zu posten und um Feedback bitten.
Ich will den Code für Tag 3 jetzt hier nicht posten, um Spoiler zu vermeiden.
Meine Lösungen sind ordentlich und funktionieren, denke ich. Dennoch sind sie sehr einfach. Wenn ich dann die Lösungen von @ThomasL sehe oder die Hinweise für @snafu denke ich immer, warum bin ich nicht darauf gekommen. Die Konzepte sind alle bekannt, aber eben nicht wirklich im "Muskelgedächtnis".
Da ich leider nie als Entwickler in einem Team gearbeitet habe, fehlt mir glaube ich externes Feedback. Pair-Programming und Code-Reviews. Naja, ich werde versuchen hier mehr zu posten und um Feedback bitten.
Ich will den Code für Tag 3 jetzt hier nicht posten, um Spoiler zu vermeiden.
In der Praxis vermeidet man allzu kreative Lösungen und man versucht auch nicht unbedingt die bestmögliche Performance zu bekommen, es sei den es ist wirklich notwendig. Insofern sind die Lösungen die du hier siehst nicht wirklich repräsentativ für Code auf den man in einem professionellen Umfeld stoßen würde.
@DasIch
Soll heißen, man schreibt lieber
weil sum(values) zu kreativ wäre?
Wobei ich die hier gezeigten Lösungen eher zu komplex bzw kompliziert gedacht finde und weniger "kreativ".
Soll heißen, man schreibt lieber
Code: Alles auswählen
result = 0
for value in values:
result = result + value
# ...
Wobei ich die hier gezeigten Lösungen eher zu komplex bzw kompliziert gedacht finde und weniger "kreativ".
- __blackjack__
- User
- Beiträge: 13250
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Also ich *muss* ``result = result + value`` schreiben, bzw. ``R=R+V``. Das BASIC kann das nicht anders.
Ich schreibe eigentlich schon so ähnlich wie in der Praxis. Und optimieren tue ich nur wenn es tatsächlich nötig ist. Was natürlich auch von der Umgebung abhängt. Bei Tag 1, Aufgabenteil 2 in Python ist „brute force“ alle Kombinationen durchgehen auf dem Desktop-PC beispielsweise kein Problem. Auf dem C64 sind die 4 Stunden und fast 45 Minuten natürlich schon ein Grund zu überlegen ob man da nicht schlauer herangehen kann. Hätte ich auch versucht wenn Benutzer Manul aus dem Raspi-Forum das nicht schon gemacht hätte.
Ich denke viele Lösungen entsprechen (hoffentlich) nicht der Praxis, weil die teilweise recht unsauber sind, eben einfach Skripte die möglichst unaufwendig das Ergebnis ausspucken. Ohne Prüfung der Eingabedaten, denn im Gegensatz zur Praxis kann man hier ja davon ausgehen, dass die valide sind. Teilweise mit schlechten/falschen Namen. Beispielsweise habe ich schon einiges von Tag 2 gesehen wo die beiden Zahlen von der Policy, die ja unterschiedliche Bedeutungen je nach Aufgabenteil haben, einfach den für Teil 1 sinnvollen Namen auch in Teil 2 verwenden, wo das verwirrend ist. Ich habe mir da tatsächlich die Mühe gemacht die umzubenennen.
Ich schreibe eigentlich schon so ähnlich wie in der Praxis. Und optimieren tue ich nur wenn es tatsächlich nötig ist. Was natürlich auch von der Umgebung abhängt. Bei Tag 1, Aufgabenteil 2 in Python ist „brute force“ alle Kombinationen durchgehen auf dem Desktop-PC beispielsweise kein Problem. Auf dem C64 sind die 4 Stunden und fast 45 Minuten natürlich schon ein Grund zu überlegen ob man da nicht schlauer herangehen kann. Hätte ich auch versucht wenn Benutzer Manul aus dem Raspi-Forum das nicht schon gemacht hätte.
Ich denke viele Lösungen entsprechen (hoffentlich) nicht der Praxis, weil die teilweise recht unsauber sind, eben einfach Skripte die möglichst unaufwendig das Ergebnis ausspucken. Ohne Prüfung der Eingabedaten, denn im Gegensatz zur Praxis kann man hier ja davon ausgehen, dass die valide sind. Teilweise mit schlechten/falschen Namen. Beispielsweise habe ich schon einiges von Tag 2 gesehen wo die beiden Zahlen von der Policy, die ja unterschiedliche Bedeutungen je nach Aufgabenteil haben, einfach den für Teil 1 sinnvollen Namen auch in Teil 2 verwenden, wo das verwirrend ist. Ich habe mir da tatsächlich die Mühe gemacht die umzubenennen.
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
- __blackjack__
- User
- Beiträge: 13250
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Hach ganz vergessen die C64 BASIC-Lösung zu Tag 3 zu posten.
Problem ist Teil 2 der im Grunde das richtige Ergebnis ausrechnet, aber leider reicht das Gleitkommaformat nicht aus um den Wert exakt zu repräsentieren. 3.5174013e+09 mag die Webseite nicht als Antwort akzeptieren.
Habe es dann noch mal in C implementiert und die 3517401300 die das ausspuckt ist richtig.
Code: Alles auswählen
10 TI$="000000":DIM M$(350),TC(5):OPEN 2,8,2,"INPUT03,S,R"
20 PRINT"READ TREE MAP ROW:":H=0
30 IF ST<>0 THEN 100
40 INPUT#2,M$(H):H=H+1:PRINT H:PRINT"{UP}";:GOTO 30
100 CLOSE 2:W=LEN(M$(0)):PRINT"READING TIME: ";TI$
110 R=1:FOR I=1 TO 5:READ SX,SY:X=0:Y=0:TC=0
120 PRINT"TREES ON SLOPE";SX;",";SY;"=";
130 IF Y>=H THEN 170
140 IF MID$(M$(Y),X+1,1)="#" THEN TC=TC+1
150 Y=Y+SY:X=X+SX:IF X>=W THEN X=X-W
160 GOTO 130
170 PRINT TC:R=R*TC:NEXT:PRINT"PART 2:";R:PRINT"TOTAL TIME:";TI$
9000 REM SLOPE X/Y PAIRS
9010 DATA 3,1, 1,1, 5,1, 7,1, 1,2
Habe es dann noch mal in C implementiert und die 3517401300 die das ausspuckt ist richtig.
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
-
- User
- Beiträge: 219
- Registriert: Donnerstag 21. Juli 2011, 07:01
- Wohnort: Stade / Hamburg
- Kontaktdaten:
Meine Lösung Tag 3 - Aufgabe 1 und 2:
Feedback ist willkommen.
Code: Alles auswählen
lines = []
with open('input_day3.txt', 'r') as f:
lines = f.readlines()
def count_trees(map, speed_x, speed_y):
position_x = 0
position_y = 0
trees = 0
width = len(lines[0])-1
height = len(lines)-1
while position_y < height:
position_x += speed_x
position_y += speed_y
if position_x >= width:
position_x = position_x - width
if lines[position_y][position_x] == '#':
trees += 1
return(trees)
first = count_trees(lines, 1, 1)
second = count_trees(lines, 3, 1)
third = count_trees(lines, 5, 1)
fourth = count_trees(lines, 7, 1)
fifth = count_trees(lines, 1, 2)
print('Aufgabe 1: ', second)
print('Aufgabe 2: ', first * second * third * fourth * fifth)
Hui, bei Tag 4 hat sich gezeigt, wie fehleranfällig reguläre Ausdrücke sein können (natürlich nur bei falscher Anwendung). Warum erhalte ich immer einen zu hohen Wert an gültigen Dokumenten? Tja, ein "\d{9}" matcht halt auch zehnstellige PIDs. Erst durch Umschreiben in String-Operationen ist mir das aufgefallen. fullmatch() schafft Abhilfe, oder ans Ende ein $ schreiben oder das Zeug einfach ganz weglassen und mit Bordmitteln lösen. Nun ist die Aufgabe aber gelöst.
- __blackjack__
- User
- Beiträge: 13250
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Tag 4 in C64 BASIC:
@Bolitho: Im BASIC-Programm habe ich die breite der Karte ja auch ggf. von der X-Position abgezogen, aber auch nur weil das C64-BASIC keinen Modulo-Operator hat. Der wäre ”sicherer”. In meiner Python-Lösung habe ich den beim Zugriff auf die Karte angewendet.
``lines = []`` am Anfang ist überflüssig. Diese leere Liste wird ja nirgends verwendet.
Ich würde sagen Dein Umgang mit `height` ist fehlerhaft. Du hast anscheinend Glück gehabt, das bei Deinen Kartendaten bei allen Steigungen in der letzten Kartenzeile kein Baum getroffen wird.
Nummerierte Namen werden nicht besser wenn man die Nummern als Worte ausschreibt.
Und natürlich: Iiiiiih, globale Variablen!
Code: Alles auswählen
10 TI$="000000":CR$=CHR$(13):PN=1:R1=0:R2=0:OPEN 2,8,2,"INPUT04,S,R"
20 PRINT"CHECK PASSPORTS..."
50 IF ST<>0 THEN 9999
60 PRINT PN:PRINT"{UP}";:PN=PN+1
100 REM READ PASSPORT
110 BY$="":IY$="":EY$="":HG$="":HC$="":EC$="":PI$="":T$=""
120 GET#2,C$:IF ST<>0 OR C$=CR$ AND C$=T$ THEN 500
130 GET#2,C2$:GET#2,C3$:K$=C$+C2$+C3$:GET#2,C$:REM READ KEY, SKIP ":"
140 V$=""
150 GET#2,C$
160 IF C$=" " OR C$=CR$ THEN T$=C$:GOTO 180
170 V$=V$+C$:GOTO 150
180 REM PRINT"<"K$"> <"V$">"
190 IF K$="BYR" THEN BY$=V$:GOTO 280
200 IF K$="IYR" THEN IY$=V$:GOTO 280
210 IF K$="EYR" THEN EY$=V$:GOTO 280
220 IF K$="HGT" THEN HG$=V$:GOTO 280
230 IF K$="HCL" THEN HC$=V$:GOTO 280
240 IF K$="ECL" THEN EC$=V$:GOTO 280
250 IF K$="PID" THEN PI$=V$:GOTO 280
260 IF K$="CID" THEN 280:REM IGNORE COUNTRY ID
270 PRINT"ERROR: INVALID KEY FOUND: "K$:END
280 GOTO 120
500 REM CHECK IF DATA IS COMPLETE
510 IF BY$="" OR IY$="" OR EY$="" OR HG$="" THEN 50
520 IF HC$="" OR EC$="" OR PI$="" THEN 50
530 R1=R1+1
600 REM CHECK VALUES
610 IF LEN(BY$)<>4 OR LEN(IY$)<> 4 OR LEN(EY$)<>4 THEN 50
620 IF LEN(HC$)<>7 OR LEN(PI$)<>9 THEN 50
630 V=VAL(BY$):IF V<1920 OR V>2002 THEN 50
640 V=VAL(IY$):IF V<2010 OR V>2020 THEN 50
650 V=VAL(EY$):IF V<2020 OR V>2030 THEN 50
700 U$=RIGHT$(HG$,2):IF U$="CM" THEN A=150:B=193:GOTO 730
710 IF U$="IN" THEN A=59:B=76:GOTO 730
720 GOTO 50
730 V=VAL(LEFT$(HG$,LEN(HG$)-2)):IF V<A OR V>B THEN 50
800 IF LEFT$(HC$,1)<>"#" THEN 50
810 FOR I=2 TO LEN(HC$):C$=MID$(HC$,I,1)
820 IF NOT(C$>="0" AND C$<="9" OR C$>="A" AND C$<="F") THEN 50
830 NEXT
900 T=EC$<>"AMB" AND EC$<>"BLU" AND EC$<>"BRN" AND EC$<>"GRY" AND EC$<>"GRN"
910 IF T AND EC$<>"HZL" AND EC$<>"OTH" THEN 50
1000 FOR I=1 TO LEN(PI$):C$=MID$(PI$,I,1):IF C$<"0" OR C$>"9" THEN 50
1010 NEXT
9000 R2=R2+1:GOTO 50
9999 CLOSE 2:PRINT"PART 1:"R1:PRINT"PART 2:"R2:PRINT"TIME: "TI$:END
``lines = []`` am Anfang ist überflüssig. Diese leere Liste wird ja nirgends verwendet.
Ich würde sagen Dein Umgang mit `height` ist fehlerhaft. Du hast anscheinend Glück gehabt, das bei Deinen Kartendaten bei allen Steigungen in der letzten Kartenzeile kein Baum getroffen wird.
Nummerierte Namen werden nicht besser wenn man die Nummern als Worte ausschreibt.
Und natürlich: Iiiiiih, globale Variablen!
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
-
- User
- Beiträge: 219
- Registriert: Donnerstag 21. Juli 2011, 07:01
- Wohnort: Stade / Hamburg
- Kontaktdaten:
Danke für die Hinweise, __blackjack__.
Code: Alles auswählen
import math
with open('input_day3.txt', 'r') as f:
lines = f.readlines()
def count_trees(map, speed_x, speed_y):
position_x = speed_x
position_y = speed_y
trees = 0
width = len(map[0])-1
height = len(map)-1
while position_y <= height:
if position_x >= width:
position_x = position_x % width
if lines[position_y][position_x] == '#':
trees += 1
position_x += speed_x
position_y += speed_y
return(trees)
# Part 1
print('Aufgabe 1: ', count_trees(lines, 3, 1))
# Part 2
slopes = [(1,1), (3,1), (5,1), (7,1), (1,2)]
solutions = [count_trees(lines, x, y) for x, y in slopes]
print('Aufgabe 2: ', math.prod(solutions))
Teil 1 war heute mit AWK wieder gut machbar:
Teil 2 hat ein paar Zeilen mehr gebraucht:
Code: Alles auswählen
awk 'BEGIN{RS="\n\n"}{sub("\n", " ")}NF==8 || NF==7 && !/cid/{counter+=1}END{print counter}' day04.txt
Code: Alles auswählen
#!/usr/bin/gawk -f
BEGIN {
RS = "[ \n]"
FS = ":"
}
/^byr/ {if ($2 >= 1920 && $2 <= 2002) fields += 1}
/^iyr/ {if ($2 >= 2010 && $2 <= 2020) fields += 1}
/^eyr/ {if ($2 >= 2020 && $2 <= 2030) fields += 1}
/^hgt.*in/ {
sub(/in/, "")
if ($2 >= 59 && $2 <= 76) fields += 1
}
/^hgt.*cm/ {
sub(/cm/, "")
if ($2 >= 150 && $2 <= 193) fields += 1
}
/^hcl/ {if ($2 ~ /#[a-f0-9]{6}$/) fields += 1}
/^ecl/ {if ($2 ~ /^(amb|blu|brn|gry|grn|hzl|oth)$/) fields +=1}
/^pid/ {if ($2 ~ /^[0-9]{9}$/) fields +=1}
/^$/ {
if (fields > 6) {valid_counter += 1}
fields = 0
}
END {print valid_counter}
-
- User
- Beiträge: 219
- Registriert: Donnerstag 21. Juli 2011, 07:01
- Wohnort: Stade / Hamburg
- Kontaktdaten:
Bei Tag 4 wurden die Pässe in der Datei durch eine Leerzeile getrennt, aber am Ende der Datei gab es keine Leerzeile. Wie kann ich den letzten Pass geschickt mitbedenken, ohne eine Ausnahmebehandlung zu haben? Also ich habe die Pässe zeilenweise eingelesen und bei einer Leerzeile den Pass in eine Liste weggespeichert und einen neuen Pass ausgelesen. Am Ende hatte ich aber noch einen Pass, der als Ausnahme am Ende der Datei der Liste hinzugefügt werden musste.
Code: Alles auswählen
# Tag 4 - Aufgabe 1
# https://adventofcode.com/2020/day/4
passports = []
valid_passports = 0
required_fields = ['byr', 'iyr' ,'eyr', 'hgt', 'hcl', 'ecl', 'pid']
with open('input_day4.txt', 'r') as f:
passport = {}
for line in f.readlines():
# append passport to list of passwords if blank line
if line == '\n':
passports.append(passport)
passport = {}
# build passport dict
else:
line = line.strip('\n')
fields = [x for x in line.split(' ')]
for field in fields:
key, value = field.split(':')
passport[key] = value
# append last passport to list
passports.append(passport)
# check passports
for passport in passports:
if all(field in passport for field in required_fields):
valid_passports += 1
print(valid_passports)
@Bolitho: Ich hatte das so gelöst:
(Die Verwendung des fileinput-Modules wird manchmal skeptisch gesehen. Mit "normalen" Datei Operationen geht es aber genau so.)
Code: Alles auswählen
def iter_passports():
passport = dict()
for line in fileinput.input():
line = line.strip()
if line:
for pair in line.split():
key, value = pair.split(':')
passport[key] = value
else:
yield passport
passport = dict()
if passport:
yield passport
-
- User
- Beiträge: 219
- Registriert: Donnerstag 21. Juli 2011, 07:01
- Wohnort: Stade / Hamburg
- Kontaktdaten:
Danke für das Teilen. Und das letzte
ist doch auch die Ausnahmebehandlung für den letzten Pass, oder? Frage mich, ob und wie man das noch wegbekommt.
Code: Alles auswählen
if passport:
yield passport
- __blackjack__
- User
- Beiträge: 13250
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Bolitho: Du könntest nach der Schleife noch mal testen ob in `passport` Werte sind und falls ja an passports anhängen. Der Test ist hier nicht nötig weil die Datei auf jeden Fall mindestens einen Reisepass enthält, aber in realen Programmen sollte man auch mit einer leeren Datei rechnen. Oder Du fügst den eingelesenen Daten künstlich eine Leerzeile hinzu, beispielsweise mit `itertools.chain()`, oder wenn man denn unbedingt alle Zeilen in eine Liste einlesen muss (warum eigentlich?) mit `append()`. Ich bin diese Entscheidung mit `more_itertools.split_at()` losgeworden.
Anmerkungen zum Quelltext: Die Kommentare im Code sind fast alle überflüssig, weil sie nur das beschreiben was der Code recht offensichtlich macht.
Dann wieder alles global und keine Unterscheidung zwischen Variablen und Konstanten. `required_fields` ist eine Konstante, sollte also KOMPLETT_GROSS geschrieben werden.
Variablen am Anfang definieren statt da wo sie verwendet werden ist so eine komische Unart die wohl noch immer von C, Pascal, und ähnlichen Sprachen kommt, wo die Sprache das (zumindest früher) erzwungen hat. Und zwar nicht weil das für Menschen einfach zu verstehen ist und zu verständlichem Quelltext führt, sondern weil die Compiler das einfacher verarbeiten konnten.
`f` ist kein guter Name. Wie wäre es mit `lines`? Und dann das `readlines()` weglassen — ich verstehe nicht warum ich diese dusselige Methode immer noch so oft sehe. Die sollte abgeschafft werden. Anfänger kommen dann gar nicht erst auf die Idee die zu verwenden, und wer dann tatsächlich mal eine Liste braucht, verwendet einfach `list()`. Was dann auch gleich mit jedem anderen iterierbaren Objekt funktioniert, und nicht nur mit Datei-Objekten. Ist ja nicht so, dass man diese dusselige `readlines()`-Methode tatsächlich brauchen würde.
Das entfernen des Zeilenendes würde ich vor dem Verarbeiten der Zeile machen. Ich finde ein ``if line:`` lesbarer als da tatsächlich einen Vergleich mit "\n" zu machen.
Was soll denn ``[x for x in line.split(" ")]``? Die `split()`-Methode liefert doch bereits eine Liste, da muss man nicht mit einer „list comprehension“ die Elemente in *noch* eine Liste kopieren.
Dann muss man nicht alles an einen Namen binden.
Da nicht wirklich sicher ist was in den Werten steht, wäre es sicherer wenn man das Aufteilen an ":" auf eine Fundstelle beschränkt. Falls ":" auch im Wert vorkommen kann. Dann wären wir bei:
Die `dict.update()`-Methode nimmt iterierbare Objekte mit Schlüssel/Wert-Paaren. Womit das zum Einzeiler wird:
Das zählen der gültigen Reisepässe könnte man mit Mengenoperationen machen, und die ``for``-Schleife durch `sum()` ersetzen.
Ungetestet:
Anmerkungen zum Quelltext: Die Kommentare im Code sind fast alle überflüssig, weil sie nur das beschreiben was der Code recht offensichtlich macht.
Dann wieder alles global und keine Unterscheidung zwischen Variablen und Konstanten. `required_fields` ist eine Konstante, sollte also KOMPLETT_GROSS geschrieben werden.
Variablen am Anfang definieren statt da wo sie verwendet werden ist so eine komische Unart die wohl noch immer von C, Pascal, und ähnlichen Sprachen kommt, wo die Sprache das (zumindest früher) erzwungen hat. Und zwar nicht weil das für Menschen einfach zu verstehen ist und zu verständlichem Quelltext führt, sondern weil die Compiler das einfacher verarbeiten konnten.
`f` ist kein guter Name. Wie wäre es mit `lines`? Und dann das `readlines()` weglassen — ich verstehe nicht warum ich diese dusselige Methode immer noch so oft sehe. Die sollte abgeschafft werden. Anfänger kommen dann gar nicht erst auf die Idee die zu verwenden, und wer dann tatsächlich mal eine Liste braucht, verwendet einfach `list()`. Was dann auch gleich mit jedem anderen iterierbaren Objekt funktioniert, und nicht nur mit Datei-Objekten. Ist ja nicht so, dass man diese dusselige `readlines()`-Methode tatsächlich brauchen würde.
Das entfernen des Zeilenendes würde ich vor dem Verarbeiten der Zeile machen. Ich finde ein ``if line:`` lesbarer als da tatsächlich einen Vergleich mit "\n" zu machen.
Was soll denn ``[x for x in line.split(" ")]``? Die `split()`-Methode liefert doch bereits eine Liste, da muss man nicht mit einer „list comprehension“ die Elemente in *noch* eine Liste kopieren.
Dann muss man nicht alles an einen Namen binden.
Da nicht wirklich sicher ist was in den Werten steht, wäre es sicherer wenn man das Aufteilen an ":" auf eine Fundstelle beschränkt. Falls ":" auch im Wert vorkommen kann. Dann wären wir bei:
Code: Alles auswählen
for field in line.split():
key, value = field.split(":", 1)
passport[key] = value
Code: Alles auswählen
passport.update(field.split(":", 1) for field in line.split())
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
# Tag 4 - Aufgabe 1
# https://adventofcode.com/2020/day/4
REQUIRED_FIELDS = frozenset(["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"])
def main():
passports = []
with open("input_day4.txt", "r") as lines:
passport = {}
for line in lines:
line = line.strip()
if line:
passport.update(field.split(":", 1) for field in line.split())
else:
passports.append(passport)
passport = {}
#
# Last passport that has no blank line after.
#
if passport:
passports.append(passport)
valid_passports = sum(
REQUIRED_FIELDS <= set(passport) for passport in passports
)
print(valid_passports)
if __name__ == "__main__":
main()
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
Wenn man es drauf anlegt z. B. so:
Code: Alles auswählen
In [1]: with open('day04.txt', 'r') as fh:
...: data = fh.read()
...:
In [2]: passports = [dict(field.split(':') for field in record.split()) for record in data.split('\n\n')]
@Bolitho: Das hat sich mit dem Vorschlag `more_itertools.split_at` von __blackjack__ überschnitten, aber wenn ich ein `.split("\n\n")` vermeiden wollte, um die Aufgabe in O(1) Speicher zu lösen, würde ich das ungefähr so machen:
Wobei ich mir damit im Prinzip nur `split_at` nachbaue.
Code: Alles auswählen
#!/usr/bin/env python3
from functools import partial
from itertools import chain
def parse_passport(lines):
# TODO
return " ".join(line.strip() for line in lines)
def parse_passports(lines):
for line in lines:
yield parse_passport(chain([line], iter(partial(next, lines), "\n")))
def main():
with open("input") as lines:
print(list(parse_passports(lines)))
if __name__ == "__main__":
main()
- __blackjack__
- User
- Beiträge: 13250
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
So furchtbar einfach heute… Für einen Samstag, wo man ja vielleicht etwas mehr Zeit erwarten könnte bei den Teilnehmern. Aber das CPGrey-Video war unterhaltsam. Ich mag den Kanal.
Code: Alles auswählen
10 ti$="000000":dim s(1023):pn=1:open 2,8,2,"input05,s,r"
20 print"scanning boarding passes..."
100 if st<>0 then close 2:goto 200
110 print pn:print"{up}";:pn=pn+1:input#2,p$:p=0:for i=1 to 10
120 p=p*2:c$=mid$(p$,i,1):if c$="B" or c$="R" then p=p+1
130 next:s(p)=-1:goto 100
200 rem search last taken seat
210 for i=1023 to 0 step -1:if s(i) then r1=i:i=0
220 next
230 rem search gap
240 for i=1 to r1-2:if s(i-1) and not s(i) then r2=i:i=1023
250 next
260 print"part 1:"r1:print"part 2:"r2:print"time: "ti$
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
-
- User
- Beiträge: 219
- Registriert: Donnerstag 21. Juli 2011, 07:01
- Wohnort: Stade / Hamburg
- Kontaktdaten:
Danke an alle für das Feedback auf mein Posting. __blackjack__ hat ja bereits eine optimierte Version meines Ansatzes gepostet. Ich habe mir das alles angesehen und hoffe, dass ich mich bei der nächsten Aufgabenstellung auch daran erinnere. Jedenfalls vielen Dank für die Hinweise und Unterstützung. Besonders an __blackjack__, bin echt beeindruckt, wie detailliert und tief dein Feedback ist. Wahnsinn.