Es wird vmtl. wieder schnell genug komplizierter Ich weiß nicht, ob das eine Besonderheit meines Inputs war (es gibt ja verschiedene), aber der "Catch", der in Teil 2 beschriebene wurde, tauchte bei mir gar nicht auf. Es gab einfach nur ein fehlendes Element im aufgespannten ID-Bereich ("set(range(min(ids), max(ids))) - set(ids)"). Könnte auch sein, dass es einfach nur das war, worauf die Aufgabe hinaus wollte. Keine Ahnung.
Advent of Code
Tag 5 in 3 Zeilen
meine erste Lösung war da noch etwas umfangreicher
Code: Alles auswählen
seatID = lambda s : int(s.replace('F','0').replace('B','1').replace('L','0').replace('R','1'), 2)
ids = set(map(seatID, open('input.txt').read().splitlines()))
print(max(ids), (set(range(min(ids), max(ids))) - ids).pop())
Code: Alles auswählen
with open('input.txt') as file:
data = [line.strip() for line in file]
def partition(cmds, letter, end, start=0):
for char in cmds:
mid = (end - start) // 2
if char == letter:
end = mid + start
else:
start = start + mid + 1
return end
def seatid(line):
row = partition(line[:-3], 'F', 127)
col = partition(line[-3:], 'L', 7)
idd = row * 8 + col
return idd
# Part 1
maxid = max(seatid(line) for line in data)
print(maxid)
# Part 2
ids = {seatid(line) for line in data}
for i in range(maxid):
if not i in ids and (i + 1) in ids and (i - 1) in ids:
print(i)
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Gegolfte Lösung für Tag 5 in Zsh (107 Zeichen):
Die Eingabedaten müssen dabei in der Datei `f` liegen.
Für Bash wird es drei Zeichen länger, anscheinend unterstützt Bash keinen Here-String alleine in einer Process-Substitution:
Code: Alles auswählen
n=`sed 'y/FLBR/0011/;s/^/ibase=2;/'<f|sort|bc`;tail -n1<<<$n;comm -23 <(seq `sed -n '1p;$p'<<<$n`) <(<<<$n)
Für Bash wird es drei Zeichen länger, anscheinend unterstützt Bash keinen Here-String alleine in einer Process-Substitution:
Code: Alles auswählen
n=`sed 'y/FLBR/0011/;s/^/ibase=2;/'<f|sort|bc`;tail -n1<<<$n;comm -23 <(seq `sed -n '1p;$p'<<<$n`) <(cat<<<$n)
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@ThomasL: Das ``.read().splitlines()`` kannst Du einfach weglassen. Das Dateiobjekt ist doch schon ein Iterator über die Zeilen. Und den ``lambda``-Ausdruck bekommt man mit der `translate()`-Methode kürzer. Dann kann man den auch direkt einsetzen und kommt mit einer Zeile weniger aus. Wobei ein Generator-Ausdruck kürzer ist als ``map(lambda s:``. Dann noch alle Namen auf einen Buchstaben begrenzen und überflüssige Leerzeichen weg, ich denke das hier ist dann ganz gut eingedampft:
Code: Alles auswählen
S=set(int(s.translate({70:48,66:49,76:48,82:49}),2)for s in open("input.txt"))
print(max(S),(set(range(min(S),max(S)))-S).pop())
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Noch mal ein Byte eingespart:
Code: Alles auswählen
S=set(int(s.translate({70:48,66:49,76:48,82:49}),2)for s in open("input.txt"))
m=max(S);print(m,(set(range(min(S),m))-S).pop())
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Cool, ich bin auch nach fast 3 Jahren immer wieder aufs neue begeistert von Python. Danke dir.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
-
- User
- Beiträge: 219
- Registriert: Donnerstag 21. Juli 2011, 07:01
- Wohnort: Stade / Hamburg
- Kontaktdaten:
@ThomasL, 3 Jahre nur? Wenn ich deinen Code lese, denke ich immer du bist ein Urgestein
Day 6: check - Schönen Nikolaustag Euch allen!
Die Lösung zu Teil 2 ist bei mir arg kompliziert. Das braucht ein Refactoring. Mal sehen, ob ich bis morgen in einer Form habe, die ich hier posten mag.
Day 6: check - Schönen Nikolaustag Euch allen!
Die Lösung zu Teil 2 ist bei mir arg kompliziert. Das braucht ein Refactoring. Mal sehen, ob ich bis morgen in einer Form habe, die ich hier posten mag.
-
- User
- Beiträge: 219
- Registriert: Donnerstag 21. Juli 2011, 07:01
- Wohnort: Stade / Hamburg
- Kontaktdaten:
Meine Lösung zu Tag 5 halte ich für ganz okay. Euer Feedback wirkt.
(und doch habe ich ein wenig Angst, __blackjack__ zu enttäuschen )
(und doch habe ich ein wenig Angst, __blackjack__ zu enttäuschen )
Code: Alles auswählen
# Tag 5
# https://adventofcode.com/2020/day/5
def main():
def decode_seat(seatcode):
row = int(seatcode[:7].replace('F', '0').replace('B', '1'), 2)
column = int(seatcode[-3:].replace('L', '0').replace('R', '1'), 2)
seat_id = row * 8 + column
return (row, column, seat_id)
# Tests
seats = [
'FBFBBFFRLR', # row 44, column 5, seat ID 357.
'BFFFBBFRRR', # row 70, column 7, seat ID 567.
'FFFBBBFRRR', # row 14, column 7, seat ID 119.
'BBFFBBFRLL' # row 102, column 4, seat ID 820.
]
print('tests: ', [decode_seat(seat) for seat in seats])
# Part 1
with open('input_day5.txt', 'r') as lines:
seat_codes = [x.strip('\n') for x in lines]
seat_ids = set(decode_seat(x)[2] for x in seat_codes)
print('Solution Part 1: ', max(seat_ids))
# Part 2
print('Solution Part 1: ', set(range(min(seat_ids), max(seat_ids)))-seat_ids)
if __name__ == "__main__":
main()
@Bolitho:
'decode_seats' kann ruhig eine globale Funktion sein. Mir fallen gerade nur zwei Gründe für Funktionen innerhalb von Funktionen ein: Entweder man braucht die speziellen Eigenschaften von Closures (z. B. für Dekoratoren), oder (sehr, sehr seltener Fall) man braucht eine Teilfunktion, die so spezifisch ist, dass sie aus keinem anderen Kontext heraus Sinn ergibt, meistens wegen ganz spezifischer Parameter/Rückgabewerte o.ä. Hier trifft keines von beiden zu.
'decode_seats' kann ruhig eine globale Funktion sein. Mir fallen gerade nur zwei Gründe für Funktionen innerhalb von Funktionen ein: Entweder man braucht die speziellen Eigenschaften von Closures (z. B. für Dekoratoren), oder (sehr, sehr seltener Fall) man braucht eine Teilfunktion, die so spezifisch ist, dass sie aus keinem anderen Kontext heraus Sinn ergibt, meistens wegen ganz spezifischer Parameter/Rückgabewerte o.ä. Hier trifft keines von beiden zu.
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Bolitho: Ein Lerneffekt könnte vielleicht noch sein, wenn Du überlegst warum man `row` und `column` eigentlich gar nicht braucht. Also was ``a * 8 + b`` auf Bitebene bedeutet, wenn man das ganze in Binärdarstellung betrachtet. Dann wird `decode_seat()` einfacher.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
-
- User
- Beiträge: 219
- Registriert: Donnerstag 21. Juli 2011, 07:01
- Wohnort: Stade / Hamburg
- Kontaktdaten:
Danke, euch beiden!
Code: Alles auswählen
# Tag 5
# https://adventofcode.com/2020/day/5
def decode_seat(seatcode):
seatcode = (
seatcode.replace("F", "0").replace("B", "1").replace("L", "0").replace("R", "1")
)
return (int(seatcode[:7], 2), int(seatcode[-3:], 2), int(seatcode, 2))
def main():
# Tests
seats = [
"FBFBBFFRLR", # row 44, column 5, seat ID 357.
"BFFFBBFRRR", # row 70, column 7, seat ID 567.
"FFFBBBFRRR", # row 14, column 7, seat ID 119.
"BBFFBBFRLL", # row 102, column 4, seat ID 820.
]
print("tests: ", [decode_seat(seat) for seat in seats])
# Part 1
with open("input_day5.txt", "r") as lines:
seat_codes = [x.strip("\n") for x in lines]
seat_ids = set(decode_seat(x)[2] for x in seat_codes)
print("Solution Part 1: ", max(seat_ids))
# Part 2
print("Solution Part 2: ", set(range(min(seat_ids), max(seat_ids))) - seat_ids)
if __name__ == "__main__":
main()
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Tag 6 in BASIC für den C64:
Code: Alles auswählen
10 TI$="000000":DIM A(25):R1=0:R2=0:GN=1:OPEN 2,8,2,"INPUT06,S,R"
20 PRINT"ASK GROUPS..."
100 IF ST<>0 THEN CLOSE 2:GOTO 9999
110 PRINT GN:PRINT"{UP}";:GN=GN+1:FOR I=0 TO 25:A(I)=0:NEXT:PC=0
200 REM ASK PERSON
210 INPUT#2,A$:IF ST<>0 OR A$="" THEN 300
220 PC=PC+1:FOR I=1 TO LEN(A$):J=ASC(MID$(A$,I,1))-65:A(J)=A(J)+1:NEXT:GOTO 200
300 REM EVALUATE GROUPS ANSWERS
310 FOR I=0 TO 25:N=A(I):IF N>0 THEN R1=R1+1
320 IF N=PC THEN R2=R2+1
330 NEXT:GOTO 100
9999 PRINT"PART 1:"R1:PRINT"PART 2:"R2:PRINT"TIME: "TI$
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Tag 5 noch ein wenig weiter gegolft (Zsh, 96 Zeichen):
Code: Alles auswählen
n(){sed 'y/FLBR/0011/;s/^/ibase=2;/'<f|sort|bc};n|tail -1;n|comm -23 <(seq `n|sed -n '1p;$p'`) -
Bei mir ging's. Habe den ersten Teil über ne Queue gelöst, wo immer die neuen "Super Bags" rein kamen und parallel dazu ein Set für die Ergebnisse. Darüber lief eine while-Schleife, die fertig ist, sobald die Queue vollständig geleert wurde - eben das Prinzip einer Warteschlange. Als Datenstruktur hab ich dafür ebenfalls ein Set genommen, um doppelte Einträge zu vermeiden.
Und Teil zwei konnte man rekursiv lösen, wenn man sich vorher eine geeignete Datenstruktur (Bags <-> Anzahl) angelegt hat. Aufpassen musste man, weil halt neben den enthaltenen Bags ja auch die Tasche an sich (quasi das jeweilige Super Bag) mitgezählt werden musste - außer auf der obersten Ebene.
Wer schon fertig ist oder sich gerne selbst betrügen möchte, kann ja mal hier in meine Lösung schauen...
https://gist.github.com/seblin/52b63d94 ... 245902ed0b
Und Teil zwei konnte man rekursiv lösen, wenn man sich vorher eine geeignete Datenstruktur (Bags <-> Anzahl) angelegt hat. Aufpassen musste man, weil halt neben den enthaltenen Bags ja auch die Tasche an sich (quasi das jeweilige Super Bag) mitgezählt werden musste - außer auf der obersten Ebene.
Wer schon fertig ist oder sich gerne selbst betrügen möchte, kann ja mal hier in meine Lösung schauen...
https://gist.github.com/seblin/52b63d94 ... 245902ed0b
Hier nochmal deutlich kompakter, wobei ich mir den rekursiven Ansatz für Schritt 1 ehrlich gesagt abgeguckt hab und nur leicht angepasst habe.
Trigger-Warnung: Nicht PEP8-konform, da Code auf Modulebene steht. Mache ich normalerweise nicht, tat ich für diese Version aber dennoch.
Trigger-Warnung: Nicht PEP8-konform, da Code auf Modulebene steht. Mache ich normalerweise nicht, tat ich für diese Version aber dennoch.
Code: Alles auswählen
import re
parse_bag = re.compile("[a-z]+ [a-z]+").match
parse_contents = re.compile("(\d+) ([a-z]+ [a-z]+)").findall
with open("day7/input.txt") as stream:
rules = {
parse_bag(line).group(): {
name: int(amount) for amount, name in parse_contents(line)
} for line in stream
}
def count_super_bags(needle):
return needle == "shiny gold" or any(map(count_super_bags, rules[needle]))
def count(needle):
return 1 + sum(amount * count(bag) for bag, amount in rules[needle].items())
print(sum(map(count_super_bags, rules)) - 1)
print(count("shiny gold") - 1)
Zuletzt geändert von snafu am Montag 7. Dezember 2020, 20:47, insgesamt 1-mal geändert.
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@snafu: Ich habe es mir im ersten Teil einfacher gemacht. Auch per rekursiven Aufrufen und die haben auch eiskalt Knoten mehrfach geliefert und am Ende erst alles ein ein `set` gekippt. Laufzeit ist auf dem Desktoprechner nicht merkbar.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman