StevenPZChan
StevenPZChan
7 min read

Categories

Tags

继续挑战,开始变得复杂了


第32题地址arecibo.html

  • 网页标题是etch-a-scetch,题目内容是Fill in the blanks源码里面有隐藏内容:

    <!– for warmup.txt –>

标题Etch A Sketch的含义是类似像素画的东西:

Etch A Sketch is a mechanical drawing toy invented by André Cassagnes of France and subsequently manufactured by the Ohio Art Company.

From wikipedia.org

而题目本身确实是一个16x16的画布,上面隐约画着一支铅笔。画布的每行左边和每列上边都有一串数字。经过画布上点击修改内容,发现这些数字表示的是这一行/列中连续的红色格子的数量组成。 这显然是一种叫数织(nonogram)的游戏:

数织是一种逻辑游戏,以猜谜的方式绘画黑白位图。在一个网格中,每一行和列都有一组数,玩家需根据它们来填满或留空格子,最后就可以由此得出一幅图画。例如,“4 8 3”的意思就是指该行或列上有三条独立的线,分别占了4、8和3格,而每条线最少要由一个空格分开。传统上,玩家是以黑色填满格子,和以“×”号标记一定不需要填充的格子。数织是一个NP完全的问题。

From wikipedia.org

所以题目应该是那个隐藏内容的文件,我们搞下来看看

import requests

with requests.Session() as sess:
    sess.auth = ('kohsamui', 'thailand')
    response = sess.get(
        'http://www.pythonchallenge.com/pc/rock/warmup.txt').text
    print(response)
# Dimensions
9 9

# Horizontal
2 1 2
1 3 1
5

7
9
3

2 3 2
2 3 2
2 3 2

# Vertical
2 1 3
1 2 3
3

8
9
8

3
1 2 3
2 1 3

求解这个游戏需要用到nonogram的库,我们安装之后试一下:

import json
import re
import requests
import nonogram_cracker

def parse_to_problem(text):
    rows_constraints = []
    cols_constraints = []
    key = None
    for line in text.splitlines():
        if re.match(r'# Dimension', line):
            key = 'd'
        elif re.match(r'# Horizon', line):
            key = 'h'
        elif re.match(r'# Vertical', line):
            key = 'v'
        elif line:
            arr = [int(s) for s in line.split()]
            if key == 'd':
                pass
            elif key == 'h':
                rows_constraints.append(arr)
            elif key == 'v':
                cols_constraints.append(arr)
    return rows_constraints, cols_constraints


with requests.Session() as sess:
    sess.auth = ('kohsamui', 'thailand')
    response = sess.get(
        'http://www.pythonchallenge.com/pc/rock/warmup.txt').text

rows, cols = parse_to_problem(response)
solution = nonogram_cracker.solve({
    'name': 'warmup',
    'rows': rows,
    'cols': cols,
})

print(json.dumps(solution, indent=2, ensure_ascii=False))
{
  "solution": [
    "██xx█xx██",
    "█xx███xx█",
    "xx█████xx",
    "x███████x",
    "█████████",
    "xxx███xxx",
    "██x███x██",
    "██x███x██",
    "██x███x██"
  ],
  "is_solved": true,
  "is_unsolvable": false,
  "has_error": false,
  "error": null
}

是一个箭头。我们来到up.html

  • 网页标题还是etch-a-scetch,题目内容告诉我们应该要去解up.txt这个题目。看来刚才只是热身。
with requests.Session() as sess:
    sess.auth = ('kohsamui', 'thailand')
    response = sess.get(
        'http://www.pythonchallenge.com/pc/rock/up.txt').text

rows, cols = parse_to_problem(response)
solution = nonogram_cracker.solve({
    'name': 'up',
    'rows': rows,
    'cols': cols,
})

print(json.dumps(solution, indent=2, ensure_ascii=False))
{
  "solution": [
    "xxxxxxxxxxxxxxxxxxx███x██xxxxxxx",
    "xxxxxxxxxxxxxxxxxx████████xxxxxx",
    "xxxxxxxxxxxxxxxxx██████████xxxxx",
    "xxxxxxxxxxxxxxxxx███xxx█xx█xxxxx",
    "xxxxxxxxxxxxxxxxx█████x██x█xxxxx",
    "xxxxxxxxxxxxxxxxx█████x██x█xxxxx",
    "xxxxxxxxxxxxxxxx████xxx█xx█xxxxx",
    "xxxxxxxxxxxxx███████████████xxxx",
    "xxxxxxxxxxx███████████████████xx",
    "xxxxxxxxxx██████x██████████████x",
    "xxxxxxxxx██████xxx█x████████████",
    "xxxxxxxxx██████xxxxx█x██████████",
    "xxxxxxxx███████xxx██xx█x████████",
    "xxxxxxxx██████x█x█x██xxx█x█x█xx█",
    "xxxxxxxx█████xxx█xx████xxxxxxxx█",
    "xxxxxxxx█████x████x█x████x█x█x█x",
    "xxxxxxxx█████xxx█x█xxx████████xx",
    "xxxxxxxxx█████x██xx█xxx████████x",
    "xxxxxxxxx██████xx█xx██xxx█x███xx",
    "xxxxxxxxxx██████x███xx██xxxxx█xx",
    "xxxxxxxxxxx██████xxx█xxx█████xxx",
    "█xxxxxxxxxxx██████xx███xxxxxxxxx",
    "██xxxxxxxxxxx███████xxx██xxxxxxx",
    "███xx███xxx██████████x████xxxxxx",
    "█████████x████████████xxxx█xxxxx",
    "██████████████████████xxxx█xxxxx",
    "x█████████████████████x████xxxxx",
    "xx█xx█████████████████xxxx█xxxxx",
    "xxx██xx████████x█████xxxxx█xxxxx",
    "xxxxxxxx██xxxxx██xxxxx████xxxxxx",
    "xxxxxxxxxx█████xx██x█xxx█xxxxxxx",
    "xxxxxxxxxxxxxxxxxxx█████xxxxxxxx"
  ],
  "is_solved": true,
  "is_unsolvable": false,
  "has_error": false,
  "error": null
}

是一个卡通的样子。等等!我们在玩Python,那当然就是python.html了。

  • 网页标题是here we go,题目新线索是"Free" as in "Free speech", not as in "free...源码里面没有隐藏内容。

那就搜一下吧。这句话其实是出自于自由软件的定义:

“Free software” means software that respects users’ freedom and community. Roughly, it means that the users have the freedom to run, copy, distribute, study, change and improve the software. Thus, “free software” is a matter of liberty, not price. To understand the concept, you should think of “free” as in “free speech,” not as in “free beer.” We sometimes call it “libre software,” borrowing the French or Spanish word for “free” as in freedom, to show we do not mean the software is gratis. You may have paid money to get copies of a free program, or you may have obtained copies at no charge. But regardless of how you got your copies, you always have the freedom to copy and change the software, even to sell copies.

From gnu.org

因此答案就是beer.html,来到了下一题。

总结:这一题还比较麻烦的,也练习到了一下一些开源三方库的使用。

本题代码地址32_arecibo.ipynb