有趣的标志!


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, 

计分

这是一个简短的python脚本,我将使用它对每个提交进行评分。

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 '16

1
@ edc65我有意选择了一个数字,该数字将使196的满分根本不可能。它更多地是关于识别图像的压缩,然后是代码高尔夫。
DJMcMayhem

只是./program < f.png仔细检查- 如果该语言无法读取文件,我们只能使用该选项吗?即使该语言可以读取文件,我们也可以使用它吗?(显然,CJam可以从文件中读取内容,我不知道)
Sp3000

这196个标志图像是您的程序必须处理的唯一输入,然后您说您的程序将不输入任何输入。这是否意味着一个文件f.png将是这196个文件中的一个。那么程序无法引用这些压缩文件?Just f.png
马特

Answers:


11

CJam,139 141

代码中有很多不可打印的东西,所以这是xxd十六进制转储:

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

您可以将二进制转储xxd -r设为可逆的吗?Cygwin应该有xxd

1
@tac不得不四处摸索,但我没有意识到Cygwin确实有它-我只需要手动选择它进行安装。下一次更新答案时,我将对其进行更新。
Sp3000

我尝试使用与莫尔斯电码相同的技术,但是我能得到的最好的方法是129个标志,我什至没有检查它是否适合256字节的限制。找到如此好的哈希表做得很好。
彼得·泰勒

12

Python 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'3

@AshwinGupta,程序读取文件,然后对其进行哈希处理。通过使用模运算符,可以将此大哈希数减少为字符串列表中的索引。
逻辑骑士

1
不确定是否会有所帮助,但是您可以做到print'...'[...:][:2]。此外,也许有一个查找表>>&一些基本的压缩?
Sp3000

@ Sp3000,双索引的想法看起来很有趣,但是我看不到它将在这里保存任何字节。我没有考虑过位操作压缩功能,但这可能会带来好处。嗯
逻辑骑士

1
双索引节省3个字节,因为您不需要保存到变量i,但是是否可以使用这些额外的字节则是一个不同的问题:P
Sp3000,2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.