Logbuch des Coders, AoC-Sternzeit 2019.40. Mit Hilfe des Traktorstrahls ist es uns gelungen, dem Sicherheitsperimeter des Planeten Neptun zu entkommen. Wir sind auf Sol IX gelandet, in der Nähe einer donutförmigen Struktur. Sie scheint ein labyrinthartiges Inneres zu haben, das wir durchqueren müssen....
Nur bin ich mit dem Einsammeln der Sterne für die vergangenen Tage furchtbar im Rückstand, ganz zu schweigen davon, dass unser Finanzkontrolleur gerade eine E-Mail geschickt hat: "Geben Sie Ihre Ausgaben für 2019 so schnell wie möglich ein". Zeit für... mehr Prokrastination, und einen kleinen Blick hin und her.
Für mich als Abendmensch ging es bei Advent of Code nie darum, die täglichen Rätsel so schnell wie möglich zu lösen. Ohne Geschwindigkeit als Hauptfaktor gibt es mehr Raum für Erkundung und Lernen. Und für einige selbst auferlegte Beschränkungen für zusätzlichen Spaß.
Als ich 2016 bei AoC anfing, kam ich zu dem (peinlichen?) Schluss, dass ich keine "richtige" Sprache mehr hatte: In meiner täglichen Arbeit als Plattform- und DevOps-Entwickler verwendete ich hauptsächlich Bash. Aber das würde doch nicht funktionieren, oder? Nun, AoC hat mir das Gegenteil bewiesen! Fast alle Rätsel waren lösbar und ich habe dabei einige nette Tricks gelernt. In meinem früheren Beitrag von 2017 finden Sie eine Zusammenfassung. Von nun an bin ich als"BashtiaanBakker" bekannt (zumindest auf unserem Xebia Slack).
Es folgten andere Sprachen wie Haskell und Go, und um einige meiner Kollegen zu ärgern, ein bisschen Brainf*ck und Whitespace.
Da mein jüngster Sohn angefangen hat, in Scratch zu programmieren, musste ich das auch ausprobieren.
Auch die großartige Open-Source-Spielengine Godot war eine gute Alternative zur ASCII-Kunst für die Visualisierung.
Aber das Beste waren die Diskussionen mit Kollegen und Freunden und das Sehen ihrer Lösungen und die der weltweiten Teilnehmer.
Ein neues Jahr, eine neue Gelegenheit, AoC zu nutzen, um zu lernen und zu erforschen, dieses Mal die Google Cloud Platform. Zuerst habe ich mit Google Cloud DataFlow / Apache Beam gespielt. Z.B. Star 2:
with beam.Pipeline(options=pipeline_options) as p:
def fuel(f):
x = int(f)
while x > 0:
x = max(0, math.floor(x / 3) - 2)
yield x
texts = (p
| 'Read' >> ReadFromText(known_args.input)
| 'Fuel' >> beam.FlatMap(fuel)
| 'Sum' >> beam.CombineGlobally(sum)
| 'Write' >> WriteToText(known_args.output)
)
Eine nette Eigenschaft ist, dass Sie denselben Code lokal, aber auch hochparallel auf automatisch bereitgestellten und skalierten Knoten ausführen können, die von Cloud DataFlow verwaltet werden - klasse!
Danach erschwerte die sequentielle Natur der meisten IntCode-basierten Rätsel die Parallelisierung.
An Tag 11 gab es dann eine andere Art von Herausforderung, die bereits in Edos Blog vorgestellt wurde: Der Code generiert eine Bitmap, die einen Text darstellt. Dann wenden wir eine Wetware OCR, unser Gehirn, an, um die eigentliche Lösung zu erhalten.
Wäre es jetzt nicht schön, wenn unser Code die OCR selbst durchführen würde? Zufälligerweise bietet die GCP Machine Learning Vision API genau das, was wir brauchen. Lassen Sie uns zunächst ein tatsächliches Bild anstelle von ASCII-Kunst erstellen. Mit der Python Pillow Bibliothek ist das ganz einfach:
# dict panels contains all painted panels...
from PIL import Image
img = Image.new('RGB', (x_size, y_size), 'black')
pixels = img.load()
for p in panels.keys():
if panels[p] == 1:
pixels[p[0],p[1]] = (255, 255, 255)
img.save("star23.png")
Jetzt müssen wir es nur noch an GCP zur Texterkennung übermitteln. Als 'Basher' wähle ich dafür das Befehlszeilentool gcloud:
$ gcloud ml vision detect-text star23.png
Wow, das sind ja eine Menge Informationen!
{
"responses": [
{
"fullTextAnnotation": {
"pages": [
...
]
},
"textAnnotations": [
{
...
},
{
"boundingPoly": {
"vertices": [
{
"x": 1
},
{
"x": 39
},
{
"x": 39,
"y": 5
},
{
"x": 1,
"y": 5
}
]
},
"description": "BLULZJLZ"
}
]
}
]
}
Wir sind nur an der "Beschreibung" interessiert. Mit ein wenig jq kommen wir zu unserer Antwort:
$ gcloud ml vision detect-text star23.png |
jq -r '.responses[0].textAnnotations[].description' | sort -u
BLULZJLZ

Großartig, das ist gelöst! Zurück an die Arbeit, all die Parkquittungen warten darauf, ins Spesensystem eingegeben zu werden :-(
Hmmm... Ich brauche nur das Datum und den Betrag von ihnen. Nun, das richtige Datum und den richtigen Betrag. Ah, das neueste Datum und der höchste Betrag sollten in Ordnung sein. Wieder zurück zu Bash!
Hier ist es also, mein hochentwickeltes receipt2json.sh Skript. Warten wir auf ein anderes Mal, um es in eine schöne Google Cloud-Funktion zu verwandeln. Zunächst einmal: Wo sind all die fehlenden Sterne...?
#!/usr/bin/env bash
textfile=$(mktemp)
gcloud ml vision detect-text "$1" | jq -r '.responses[0].textAnnotations[].description' > $textfile
amount=$(egrep -o 'b[0-9]+,[0-9]{2}b' $textfile | sort -n | tail -1 | tr , .)
date=$(egrep -o '[0-9]{2}-[0-9]{2}-(20)?(19|20)' $textfile | sort | tail -1)
rm $textfile
cat <<EOF
{ 'amount': $amount, 'date': '$date' }
EOF
Advent des Codes 2019 Serie
- Advent of Code 2019 hat begonnen - Machen Sie mit!
- Advent of Code 2019 - Tag 2
- Advent des Codes: Wie Excel mir den Tag rettete und auch meinem Sohn den Tag rettete
- Advent des Codes - Tag 4: Visualisieren
- Advent des Codes - Tag 5: Saintaerkla2s
- Advent of Code - Tag 6: Wie ich an AoC hängen geblieben bin
- Advent of Code - Tag 7: Teilen Sie Ihren Arbeitsablauf
- Advent of Code - Tag 8: Wie einfache Dinge für manche Menschen sehr schwer sein können
- Advent of Code - Tag 9: Wie ich anfing, Spaß am Lösen von Programmierrätseln zu haben
- Advent of Code - Tag 10: Weltraum-Cowboys schießen Pixel in den Himmel
- Advent des Codes - Tag 11: Sein oder nicht sein
- Advent of Code - Tag 12: Nach dem Mond schießen
- Advent des Codes - Tag 14: Kettenreaktion
- Advent des Codes - Tag 16: Flüche
- Advent of Code - Tag 17: Vakuumieren eines Gerüsts mit dem Intcode-Programm
- Wie kleine grüne Männchen mir geholfen haben, ein Rätsel zu lösen
- Advent of Code - Tag 20: Ein bisschen Überarbeitung
- Advent of Code - Tag 21: Es ist ein Marathon, kein Sprint
- Advent of Code - Tag 22: Mischen von Karten bis in alle Ewigkeit
- Advent of Code - Tag 23: Das Netzwerk ist zuverlässig
- Advent of Code - Tag 24 & 25: Unkonventionelles Denken
Verfasst von

Bastiaan Bakker
Unsere Ideen
Weitere Blogs
Contact



