Bayrakları ile eğlenceli!


20

Bayrak bayrağına bakan ve bayrağın hangi ülkeden geldiğini belirleyen 256 bayt veya daha az kaynak kodlu tam bir program yazın. Meydan okumadaki 196 farklı bayrağı içeren bir zip dosyası buradan indirilebilir . Kaynak: [ Flagpedia ]. Bu 196 bayrak görüntüleri, programınızın işlemesi gereken tek girdidir.

Programınız girdi almayacak. Bayrak resmi, programınızla aynı dizinde olacak ve "f.png" olarak adlandırılacaktır. Programınız bu dosyayı açacak, tanımlayacak ve o ülkenin iki harfli kısaltmasını yazdıracaktır . Dosyaları açamayan bir dil kullanıyorsanız, programınızı olarak çalıştırmak da kabul edilebilir ./program < f.png.

Her bayrak dosyası, beklenen çıktıyla aynı şekilde adlandırılır. 2 harfin üzerindeki tüm çıktılar yok sayılır.

Tüm çıktıların / dosya adlarının listesi:

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, 

puanlama

İşte her gönderimi puanlamak için kullanacağım kısa bir python betiği.

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")

Puanınız doğru bir şekilde tanımlanmış toplam bayrak sayısıdır. Beraberlik durumunda, daha önceki başvuru kazanır.

kurallar

  • Test kolaylığı için, Windows 10 veya Ubuntu için ücretsiz olarak kullanılabilen bir tercüman / derleyici içeren herhangi bir dil kullanılabilir.

  • Görüntü işleme kütüphanelerine izin verilir, ancak bayraklar veya ülkelerle ilgili yerleşik yapılara izin verilmez. ( öksürük Mathematica öksürük )

  • Lütfen programınızı çalıştırmak için gereken tam komutu ve gerekli kitaplıklara bağlantılar sağlayın.

  • Gönderiler "f.png" dışında hiçbir dosyayla etkileşimde bulunamaz.

  • Başvurularda zor bir zaman sınırım yok, ancak lütfen nispeten hızlı tutun. Puanlama betiğinin saatlerce sürmesini istemiyorum.


4
Bayt sınırı gerçekten düşük. Sadece 196 iki harfli kodun sıkıştırılmadan saklanması 392 bayt gerektirir
edc65

2
@ edc65 Mesele şu ki, sadece az sayıda bayrak alacaksınız.
isaacg

1
@ edc65 Kasıtlı olarak 196'da mükemmel bir skoru imkansız kılacak bir sayı seçtim. Bu daha çok kod tanıma resimlerini tanıma sıkıştırma hakkında.
DJMcMayhem

Sadece çift kontrol - ./program < f.pngseçeneği yalnızca dilin dosyaları okuma yolu yoksa kullanabilir miyiz, yoksa dil dosyaları okuyabilse bile kullanabilir miyiz? (Görünüşe göre CJam bilmediğim dosyalardan okuyabilir)
Sp3000

Bu 196 bayrak görüntüleri, programınızın işlemesi gereken tek girdidir, o zaman programınızın hiçbir girdi almayacağını söylersiniz . Bu, f.png dosyasının o 196 dosyalarından biri olacağı anlamına mı geliyor? Yani program bu sıkıştırılmış dosyalara başvuramaz mı? Sadece f.png
Matt

Yanıtlar:


11

CJam, 139 141

Kodda çok fazla yazdırılamaz, bu yüzden 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/=

Bu tam olarak 256 bayt, program yapıyor:

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

Programı komutla çalıştırın

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

Bu gönderimi çalıştırmayla ilgili yardım için @Dennis'e teşekkürler.


Herkesin bu kadarını almasına şaşırdım. 139/196 =% 70,9. A notunu not ettiniz!
Level River St

İkili çöplüğü geri xxd -rdöndürülebilir hale getirebilir misiniz ? Cygwin olmalıxxd
kedi

1
@tac Biraz dürtmek zorunda kaldım, ama Cygwin'in sahip olduğunu fark etmedim - sadece kurulum için manuel olarak seçmek zorundaydım. Cevabı bir sonraki güncellediğimde güncelleyeceğim.
Sp3000

Mors kodu ile aynı tekniği kullanmayı denedim , ancak alabildiğim en iyi 129 bayrak ve 256 bayt sınırına uyup uymadığını kontrol etmedim. Böyle iyi bir karma bulmak için aferin.
Peter Taylor

12

Python 2, Puan = 68 89

Bu çözüm, ülke kısaltmaları listesine bir dizin oluşturmak için bayrak resmi dosyasının karmasını kullanır. Bir endekse birden fazla bayrak karması varsa, yalnızca ilk kısaltma döndürülür (bu nedenle, bir grupta birden fazla ülke olan bu testlerden bazılarında başarısız olur). Ancak bu algoritma, boş olmayan her karma kova için tek bir doğru cevabı garanti eder.

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

Bu program 247 karakterdir.

Daha okunabilir bir versiyon:

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]

Kodlanmış dizeyi oluşturma

Kodlanmış dize oluşturmak için, bayrak dosyalarında dize olarak okumak, dizeden bir karma oluşturmak ve karma sınırlı sayıda karma için azaltmak için bir işlev kullanın 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

her imzayla eşleşen ülkelerin sözlüğünü döndürmek için sözlüğü arama dizesine dönüştürmek üzere bazı kodlar kullanın:

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

Hangi değerleri ile bucketsen iyi sonuçları verir biraz denemek gerekiyordu .


Bu sadece bayrağın ortalama rengini mi alıyor?
Ashwin Gupta

@AshwinGupta, program dosyayı okur sonra bir karma alır. Bu büyük karma sayı, bir modulo operatörü kullanılarak dize listesindeki bir dizine indirgenir.
Mantık Şövalyesi

1
Yardım edip etmeyeceğinden emin değilim ama yapabilirsin print'...'[...:][:2]. Ayrıca, bazı temel sıkıştırma ile >>ve &bazı için bir arama tablosu ?
Sp3000

@ Sp3000, çift endeks fikri ilginç görünüyor ama burada herhangi bir bayt nereye kaydedileceğini göremiyorum. Sıkıştırma için bit manipülasyon işlevlerini düşünmemiştim, ancak bu bir avantaj sağlayabilir. Hmmmm.
Mantık Şövalyesi

1
Çift dizinleme 3 bayt tasarruf sağlar, çünkü bir değişkene kaydetmeniz gerekmez i, ancak bu ekstra baytları kullanıp kullanamayacağınız farklı bir sorudur: P
Sp3000
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.