깃발 재미!


20

깃발의 이미지를보고 깃발의 출신 국가를 결정하는 256 바이트 이하의 소스 코드로 전체 프로그램을 작성하십시오. 챌린지에 196 개의 다른 플래그를 포함하는 zip 파일은 여기 에서 다운로드 할 수 있습니다 . 출처 : [ Flagpedia ]. 이 196 개의 플래그 이미지는 프로그램이 처리해야하는 유일한 입력입니다.

프로그램은 입력을받지 않습니다. 플래그 이미지는 프로그램과 같은 디렉토리에 있으며 이름은 "f.png"입니다. 프로그램에서이 파일을 열고 식별 한 다음 해당 국가 의 두 글자 약어를 인쇄합니다 . 파일을 열 수없는 언어를 사용하는 경우 프로그램을로 실행해도됩니다 ./program < f.png.

각 플래그 파일의 이름은 예상 출력과 동일합니다. 2 자 이상의 모든 출력은 무시됩니다.

다음은 모든 출력 / 파일 이름 목록입니다.

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, 

채점

다음은 각 제출 점수를 매기는 데 사용하는 간단한 파이썬 스크립트입니다.

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

점수는 올바르게 식별 된 총 플래그 수입니다. 동점 인 경우, 이전 제출물이 이깁니다.

규칙

  • 테스트 편의를 위해 Windows 10 또는 Ubuntu 용 무료 통역사 / 컴파일러가있는 모든 언어를 사용할 수 있습니다.

  • 이미지 처리 라이브러리는 허용되지만 플래그 또는 국가와 관련된 모든 내장은 허용되지 않습니다. ( 기침 Mathematica 기침 )

  • 필요한 라이브러리에 대한 링크와 함께 프로그램을 실행하는 데 필요한 전체 명령을 제공하십시오.

  • 제출물은 "f.png"이외의 파일과 상호 작용할 수 없습니다.

  • 제출에 시간 제한이 없지만 상대적으로 빨리 유지하십시오. 점수 매기기 스크립트에 몇 시간이 걸리지 않기를 바랍니다.


4
바이트 제한이 실제로 낮습니다. 그냥 압축되지 않은 196 두 문자 코드를 저장하는 392 바이트가 필요합니다
edc65

2
@ edc65 요점은 적은 수의 플래그 만 얻는다는 것입니다.
isaacg

1
@ edc65 나는 의도적으로 196의 완벽한 점수를 만들 수없는 숫자를 골랐다. 이미지를 압축 한 다음 codegolf를 압축하는 것에 관한 것입니다.
DJMcMayhem

다시 한 번만 ./program < f.png확인하면 언어에 파일을 읽을 수있는 방법이없는 경우 에만 옵션을 사용할 수 있습니까? 아니면 언어가 파일을 읽을 수있는 경우에도이 옵션을 사용할 수 있습니까? (확실히 CJam은 내가 알지 못하는 파일을 읽을 수 있음)
Sp3000

이 196 개 플래그 이미지 만 입력 프로그램이 처리해야된다 당신이 말하는 당신의 프로그램이 더 입력을하지 않습니다 . 이것은 f.png 파일 하나가 196 파일 중 하나라는 것을 의미합니까? 그래서 프로그램이 압축 파일을 참조 할 수 없습니까? Just f.png
Matt

답변:


11

CJam, 139 141

코드에는 인쇄 할 수없는 항목이 많으므로 다음은 xxd16 진수 덤프입니다.

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/=

프로그램이 다음과 같이 정확히 256 바이트입니다.

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

명령을 사용하여 프로그램을 실행하십시오.

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

이 제출 작업을 수행하는 데 도움을 주신 @Dennis에게 감사드립니다.


나는 누군가가 이것을 많이 가지고 놀랐습니다. 139/196 = 70.9 %. A 등급을 긁었습니다!
Level River St

바이너리 덤프를 xxd -r뒤집을 수있는 것으로 만들 수 있습니까? Cygwin은 다음을 가져야합니다xxd
cat

1
@tac 약간 찔 렀지 만 Cygwin이 가지고 있다는 것을 몰랐습니다. 설치를 위해 수동으로 선택해야했습니다. 다음에 답변을 업데이트하면 업데이트하겠습니다.
Sp3000

Morse code 와 동일한 기술을 사용해 보았지만 얻을 수있는 최선은 129 플래그이며 256 바이트 제한에 맞는지조차 확인하지 못했습니다. 좋은 해시를 찾는 것이 좋습니다.
피터 테일러

12

파이썬 2, 점수 = 68 89

이 솔루션은 플래그 이미지 파일의 해시를 사용하여 국가 약어 목록에 색인을 만듭니다. 인덱스에 둘 이상의 플래그가 해시되면 첫 번째 약어 만 반환되므로 해시 버킷에서 둘 이상의 국가에 대한 테스트 중 일부가 실패합니다. 그러나이 알고리즘은 비어 있지 않은 해시 버킷마다 하나의 정답을 보장합니다.

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

이 프로그램은 247 자입니다.

더 읽기 쉬운 버전 :

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]

인코딩 된 문자열 작성

인코딩 된 문자열을 작성하려면 플래그 파일을 문자열로 읽고 문자열에서 해시를 생성하고 해시를 제한된 수의 해시로 줄이는 함수를 사용합니다 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

각 서명과 일치하는 국가 사전을 반환하려면 코드를 사용하여 사전을 조회 문자열로 변환하십시오.

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

값이 buckets가장 좋은 결과 를 제공 하는 비트를 실험해야했습니다 .


이것은 단지 국기의 평균 색상을 취합니까?
Ashwin Gupta 5

@AshwinGupta에서 프로그램은 파일을 읽은 다음 해시를 가져옵니다. 이 큰 해시 수는 모듈러스 연산자를 사용하여 문자열 목록의 색인으로 줄어 듭니다.
논리 기사

1
도움이 될지 확실하지 않지만 할 수 있습니다 print'...'[...:][:2]. 또한, 어쩌면이있는 조회 테이블 >>&몇 가지 기본적인 압축?
Sp3000

@ Sp3000, 이중 인덱스 아이디어는 흥미롭게 보이지만 여기에 바이트를 저장할 위치를 알 수 없습니다. 압축을위한 비트 조작 기능은 고려하지 않았지만 이점이 있습니다. 흠.
논리 기사

1
이중 인덱싱은 변수에 저장할 필요가 없기 때문에 3 바이트를 절약 i하지만 여분의 바이트를 사용할 수 있는지 여부는 다른 질문입니다. : P
Sp3000
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.