Spaß mit Flaggen!


20

Schreiben Sie ein vollständiges Programm mit einem Quellcode von 256 Byte oder weniger, das ein Bild einer Flagge anzeigt und feststellt, aus welchem ​​Land diese Flagge stammt. Eine Zip-Datei mit den 196 verschiedenen Flags der Challenge kann hier heruntergeladen werden . Quelle: [ Flagpedia ]. Diese 196 Flag-Bilder sind die einzigen Eingaben, die Ihr Programm verarbeiten muss.

Ihr Programm nimmt keine Eingabe entgegen. Das Flag-Image befindet sich im selben Verzeichnis wie Ihr Programm und heißt "f.png". Ihr Programm öffnet diese Datei, identifiziert sie und druckt die zweibuchstabige Abkürzung für dieses Land . Wenn Sie eine Sprache verwenden, die keine Dateien öffnen kann, können Sie Ihr Programm auch als ausführen ./program < f.png.

Jede Flag-Datei hat den gleichen Namen wie die erwartete Ausgabe. Alle Ausgaben über 2 Buchstaben werden ignoriert.

Hier ist eine Liste aller Ausgaben / Dateinamen:

ad, ae, af, ag, al, am, ao, ar, at, au, az, ba, bb, bd, be, bf, bg, bh, bi, bj,
bn, bo, br, bs, bt, bw, by, bz, ca, cd, cf, cg, ch, ci, cl, cm, cn, co, cr, cu,
cv, cy, cz, de, dj, dk, dm, do, dz, ec, ee, eg, eh, er, es, et, fi, fj, fm, fr,
ga, gb, gd, ge, gh, gm, gn, gq, gr, gt, gw, gy, hn, hr, ht, hu, id, ie, il, in,
iq, ir, is, it, jm, jo, jp, ke, kg, kh, ki, km, kn, kp, kr, ks, kw, kz, la, lb,
lc, li, lk, lr, ls, lt, lu, lv, ly, ma, mc, md, me, mg, mh, mk, ml, mm, mn, mr,
mt, mu, mv, mw, mx, my, mz, na, ne, ng, ni, nl, no, np, nr, nz, om, pa, pe, pg,
ph, pk, pl, pt, pw, py, qa, ro, rs, ru, rw, sa, sb, sc, sd, se, sg, si, sk, sl,
sm, sn, so, sr, st, sv, sy, sz, td, tg, th, tj, tl, tm, tn, to, tr, tt, tv, tw,
tz, ua, ug, us, uy, uz, va, vc, ve, vn, vu, ws, ye, za, zm, zw, 

Wertung

Hier ist ein kurzes Python-Skript, mit dem ich jede Einreichung bewerten werde.

import os
import subprocess
import random

botlist = []
with open("bots.txt") as bots:
    for line in bots:
        line = line.split(", ")
        if len(line) >= 2:
            botLine = line + [0]
            botlist.append(botLine)

files = os.listdir(os.getcwd() + "/flags")
random.shuffle(files)

def test(bot_command):
    score = 0
    for filename in files:
        command = "COPY flags\\{} f.png".format(filename)
        os.system(command)

        print bot_command

        result = subprocess.check_output(bot_command, shell = True)
        if result[:2] == filename[:2]:
            score += 1

    return score

for i in range(len(botlist)):
    command = botlist[i][1]
    botlist[i][2] = test(command)

with open("output.txt", "w+") as output:
    for bot in botlist:
        output.write("{} got a score of {}.".format(bot[0], bot[2]))

os.system("del f.png")

Ihre Punktzahl ist die Gesamtzahl der korrekt identifizierten Flaggen. Im Falle eines Gleichstands gewinnt die frühere Einreichung.

Regeln

  • Für meinen Testkomfort kann jede Sprache mit einem frei verfügbaren Interpreter / Compiler für Windows 10 oder Ubuntu verwendet werden.

  • Bildverarbeitungsbibliotheken sind zulässig, jedoch sind keine mit Flaggen oder Ländern verknüpften eingebauten Bibliotheken zulässig. ( Husten Mathematica Husten )

  • Bitte geben Sie den vollständigen Befehl ein, der zum Ausführen Ihres Programms erforderlich ist, sowie Links zu den erforderlichen Bibliotheken.

  • Einsendungen dürfen mit keiner Datei außer "f.png" interagieren.

  • Ich habe kein festes Zeitlimit für die Einreichung, aber bitte behalte es relativ schnell bei. Ich möchte nicht, dass das Scoring-Skript Stunden dauert.


4
Die Bytegrenze ist wirklich niedrig. Nur das Speichern der 196 unkomprimierten Zwei-Buchstaben-Codes erfordert 392 Bytes
edc65

2
@ edc65 Der Punkt ist, dass Sie nur eine kleine Anzahl von Flags erhalten.
Isaacg

1
@ edc65 Ich habe absichtlich eine Zahl gewählt, die ein perfektes Ergebnis von 196 im Grunde unmöglich machen würde. Es geht mehr um die Komprimierung der Erkennung von Bildern als um Codegolf.
DJMcMayhem

Nur nochmal überprüfen - können wir die ./program < f.pngOption nur verwenden, wenn die Sprache keine Möglichkeit zum Lesen von Dateien hat, oder können wir sie auch verwenden, selbst wenn die Sprache Dateien lesen kann? (Anscheinend kann CJam aus Dateien lesen, die ich nicht kannte)
Sp3000

Diese 196 Flag-Bilder sind die einzigen Eingaben, die Ihr Programm verarbeiten muss, wenn Sie sagen, dass Ihr Programm keine Eingaben vornehmen wird . Bedeutet das, dass die eine Datei f.png eine dieser 196 ist. Das Programm kann also nicht auf diese gezippten Dateien verweisen? Just f.png
Matt

Antworten:


11

CJam, 139 141

Der Code enthält viele nicht druckbare Dateien. Hier ist der xxdHexdump:

00000000: 7132 3925 3162 226d cec5 9635 b14b 69ee  q29%1b"m...5.Ki.
00000010: d9d0 66e8 97b8 e88d 2366 7857 9595 1c73  ..f.....#fxW...s
00000020: 9324 11b2 ddb8 7a3f 19ed bd37 07c0 cb86  .$....z?...7....
00000030: 394e b34a ecf0 8c9b f300 a216 2e2e 594a  9N.J..........YJ
00000040: 9a6b 3b2f 250a 9a25 783b 0e49 3e9c 6ab9  .k;/%..%x;.I>.j.
00000050: 8d6d d729 42d0 85f3 657b 7d86 af48 c6cb  .m.)B...e{}..H..
00000060: f7ff 980f b81c dd5e e8cb 4e34 d8ec edca  .......^..N4....
00000070: 6646 1b4d 7605 8937 ed58 2302 1cc1 ebfd  fF.Mv..7.X#.....
00000080: 16d3 b53e 3e2c d879 fe33 feef dd65 d49f  ...>>,.y.3...e..
00000090: 5d73 7ced 92e6 9526 c186 00bf d2a8 ffaa  ]s|....&........
000000a0: 65a0 3001 f42a 94d7 592f ebe7 8bdf 97a7  e.0..*..Y/......
000000b0: 0681 8ee1 9e0e 424b f6a1 4c50 1c8a 8de5  ......BK..LP....
000000c0: 481a 388c 6eaa 0c43 e1db 69df 567b 323f  H.8.n..C..i.V{2?
000000d0: 2573 c4ce b348 6fff 37e0 55b4 7c9a 7e7d  %s...Ho.7.U.|.~}
000000e0: 73a4 ef74 2b99 b765 2a2d d99f 986a 355c  s..t+..e*-...j5\
000000f0: db22 3236 3362 3236 6227 6166 2b32 2f3d  ."263b26b'af+2/=

Dies sind genau 256 Bytes, wobei das Programm Folgendes ausführt:

q29%                          Read input and keep every 29th char
    1b                        Sum code points
      "..."                   Push long string
           263b               Convert long string to base 263
               26b            Convert result to base 26
                  'af+        Add 'a to each element in the resulting array
                      2/      Split into chunks of length 2
                        =     Index sum cyclically to extract output

Führen Sie das Programm mit dem Befehl aus

java -Dfile.encoding=ISO-8859-1 -jar cjam-0.6.5.jar flags.cjam < f.png

Vielen Dank an @Dennis für die Hilfe, um diese Einsendung zum Laufen zu bringen.


Ich bin erstaunt, dass jemand so viele hat. 139/196 = 70,9%. Sie haben die Note A erreicht!
Level River St

Könnten Sie den xxd -rBinärdump zu einem -reversiblen machen? Cygwin hättexxd
Katze

1
@tac Musste ein bisschen herumstöbern, aber ich wusste nicht, dass Cygwin es hat - ich musste es nur manuell für die Installation auswählen. Ich werde es aktualisieren, wenn ich die Antwort das nächste Mal aktualisiere.
Sp3000

Ich habe versucht, die gleiche Technik wie für Morse-Code zu verwenden , aber das Beste, was ich bekommen konnte, sind 129 Flags, und ich habe nicht einmal geprüft, ob das in das 256-Byte-Limit passt. Gut gemacht, dass Sie so einen guten Hash gefunden haben.
Peter Taylor

12

Python 2, Score = 68 89

Diese Lösung verwendet den Hash der Flag-Image-Datei, um einen Index für eine Liste der Länderabkürzungen zu erstellen. Wenn mehr als ein Flag in einem Index gehasht wurde, wird nur die erste Abkürzung zurückgegeben (sodass einige dieser Tests mit mehr als einem Land in einem Hash-Bucket fehlschlagen). Dieser Algorithmus garantiert jedoch eine korrekte Antwort für jeden nicht leeren Hash-Bucket.

i=hash(open('f.png').read())%99*2
print'kgmviruasefridusvakpsmbtgrpwcdsdauninrsyalsg--game--espyscmtyebhgqom--kh--inhudjbw--ltroilbicv--jonaugke--svhtbg--simcknbnpelcplgncmmacimytnttlytgcflirsvemhtzuyqaerbfbepa--uzaenearcl--jmbbphkzrwieet'[i:i+2]

Dieses Programm hat 247 Zeichen.

Eine lesbarere Version:

encoded = 'kgmviruasefridusvakpsmbtgrpwcdsdauninrsyalsg--game--espyscmtyebhgqom--kh--inhudjbw--ltroilbicv--jonaugke--svhtbg--simcknbnpelcplgncmmacimytnttlytgcflirsvemhtzuyqaerbfbepa--uzaenearcl--jmbbphkzrwieet'
index = hash(open('f.png').read())%99 * 2
print encoded[index : index+2]

Erstellen der codierten Zeichenfolge

Um die codierte Zeichenfolge zu erstellen, benutze ich eine Funktion, um die Flag-Dateien als Zeichenfolgen einzulesen, einen Hash aus der Zeichenfolge zu generieren und den Hash auf eine begrenzte Anzahl von Hashs zu reduzieren buckets:

def encode(buckets):
    lookup = {}
    for fn in os.listdir('flags'):
        name = fn[:2]
        signature = hash(open('flags/'+fn).read()) % buckets
        lookup[signature] = lookup.get(signature, '')+name
    return lookup

Um ein Wörterbuch mit Ländern zurückzugeben, die mit jeder Signatur übereinstimmen, verwenden Sie einen Code, um das Wörterbuch in eine Suchzeichenfolge zu konvertieren:

encoded = ''.join(lookup.get(v, '--')[:2] for v in range(buckets))

Ich musste ein bisschen experimentieren, mit welchen Werten von bucketsdie besten Ergebnisse erzielt werden.


Nimmt dies nur die durchschnittliche Farbe der Flagge an?
Ashwin Gupta

@AshwinGupta, das Programm liest die Datei ein und nimmt dann einen Hash davon. Diese große Hash-Zahl wird mithilfe eines Modulo-Operators auf einen Index in einer String-Liste reduziert.
Logic Knight

1
Ich bin mir nicht sicher, ob es helfen wird, aber du kannst es tun print'...'[...:][:2]. Vielleicht auch eine Nachschlagetabelle mit >>und &für eine grundlegende Komprimierung?
Sp3000

@ Sp3000, die Idee mit dem doppelten Index sieht interessant aus, aber ich kann nicht sehen, wo hier Bytes gespeichert werden. Ich hatte Bitmanipulationsfunktionen für die Komprimierung nicht in Betracht gezogen, aber das könnte einen Vorteil bieten. Hmmmm.
Logic Knight

1
Doppelte Indizierung spart 3 Bytes, weil Sie nicht in einer Variablen speichern müssen i, aber ob Sie diese zusätzlichen Bytes verwenden können oder nicht, ist eine andere Frage: P
Sp3000
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.