Advent of Code

Gute Links und Tutorials könnt ihr hier posten.
Bolitho
User
Beiträge: 219
Registriert: Donnerstag 21. Juli 2011, 07:01
Wohnort: Stade / Hamburg
Kontaktdaten:

Day 3: check :)

Bild

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.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

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.
Benutzeravatar
snafu
User
Beiträge: 6752
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@DasIch
Soll heißen, man schreibt lieber

Code: Alles auswählen

result = 0
for value in values:
    result = result + value
# ...
weil sum(values) zu kreativ wäre? :ugeek:

Wobei ich die hier gezeigten Lösungen eher zu komplex bzw kompliziert gedacht finde und weniger "kreativ". :)
Benutzeravatar
__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.
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.
Benutzeravatar
__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. 🙂

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
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.
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.
Bolitho
User
Beiträge: 219
Registriert: Donnerstag 21. Juli 2011, 07:01
Wohnort: Stade / Hamburg
Kontaktdaten:

Day 4: check
Bild
Bolitho
User
Beiträge: 219
Registriert: Donnerstag 21. Juli 2011, 07:01
Wohnort: Stade / Hamburg
Kontaktdaten:

Meine Lösung Tag 3 - Aufgabe 1 und 2:

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)
       
Feedback ist willkommen.
Benutzeravatar
snafu
User
Beiträge: 6752
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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. :)
Benutzeravatar
__blackjack__
User
Beiträge: 13250
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Tag 4 in C64 BASIC:

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
@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!
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.
Bolitho
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))
nezzcarth
User
Beiträge: 1649
Registriert: Samstag 16. April 2011, 12:47

Teil 1 war heute mit AWK wieder gut machbar:

Code: Alles auswählen

awk 'BEGIN{RS="\n\n"}{sub("\n", " ")}NF==8 || NF==7 && !/cid/{counter+=1}END{print counter}' day04.txt
Teil 2 hat ein paar Zeilen mehr gebraucht:

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}
Bolitho
User
Beiträge: 219
Registriert: Donnerstag 21. Juli 2011, 07:01
Wohnort: Stade / Hamburg
Kontaktdaten:

Tag 5 check - da bin ich schon sehr gespannt auf andere, effizientere Lösungen. Glaube, ich war viel zu umständlich bei decodieren. :)
Bild
Bolitho
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)
nezzcarth
User
Beiträge: 1649
Registriert: Samstag 16. April 2011, 12:47

@Bolitho: Ich hatte das so gelöst:

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
(Die Verwendung des fileinput-Modules wird manchmal skeptisch gesehen. Mit "normalen" Datei Operationen geht es aber genau so.)
Bolitho
User
Beiträge: 219
Registriert: Donnerstag 21. Juli 2011, 07:01
Wohnort: Stade / Hamburg
Kontaktdaten:

Danke für das Teilen. Und das letzte

Code: Alles auswählen

    if passport:
        yield passport
ist doch auch die Ausnahmebehandlung für den letzten Pass, oder? Frage mich, ob und wie man das noch wegbekommt.
Benutzeravatar
__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:

Code: Alles auswählen

                for field in line.split():
                    key, value = field.split(":", 1)
                    passport[key] = value
Die `dict.update()`-Methode nimmt iterierbare Objekte mit Schlüssel/Wert-Paaren. Womit das zum Einzeiler wird:

Code: Alles auswählen

                passport.update(field.split(":", 1) for field in line.split())
Das zählen der gültigen Reisepässe könnte man mit Mengenoperationen machen, und die ``for``-Schleife durch `sum()` ersetzen.

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.
nezzcarth
User
Beiträge: 1649
Registriert: Samstag 16. April 2011, 12:47

Bolitho hat geschrieben: Samstag 5. Dezember 2020, 11:31 Frage mich, ob und wie man das noch wegbekommt.
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')]
Ich halte das aber für keine so gute Lösung.
narpfel
User
Beiträge: 646
Registriert: Freitag 20. Oktober 2017, 16:10

@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:

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()
Wobei ich mir damit im Prinzip nur `split_at` nachbaue.
Benutzeravatar
__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.
Bolitho
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.
Antworten