关卡地址

解决方案:

思路:

这一关大图下面有个小图,查看源代码后发现是10000*1的图片显示为100*100

100 × 100 pixels (Natural: 10000 × 1 pixels)

同时还有一个提示:

remember: 100*100 = (100+99+99+98) + (…

结合标题,需要将10000*1的图片重新组合为100*100的图片,排列规律如下:

—————————————100-—————————————
|————————————98——————————————|
|   |   ................. |  |
|   |   ................. |  |
|   |   ................. |  |
98  96  ................. 97 99
|   |   ................. |  |
|   |   ................. |  |
|   |   ................. |  |
|   |   ................. |  |
| ——————————97————————————|  |
————————————99————————————————

如果一行一行排列像素会得到bit这个结果,然后得到如下提示:

you took the wrong curve.

正确的结果会得到一只猫的图片,输入cat会得到如下提示:

and its name is uzi. you’ll hear from him later.

代码:

Challenge014.py

import helper
path=".\\Data\\014"
helper.ensureDir(path)

# ================================

# 使用http认证,下载文件

import urllib.request
helper.installHTTPBasicAuthOpener("huge", "file")

wire="http://www.pythonchallenge.com/pc/return/wire.png"
(filename, headers)=urllib.request.urlretrieve(wire, path+"\\wire.png")
# ================================


from PIL import Image
im=Image.open(filename)
# px=im.load()

# (w,h)=im.size


def officialSolution():
    tmp=spiral(im)
    tmp.close()

def mySolution():
    tmp=efficientSpiral(im)
    tmp.close()

def efficientSpiral(source):
    px=source.load()
    newIm=Image.new(source.mode, (100,100))
    newPx=newIm.load()
    hLines,vLines=0,0
    xStep,yStep=1,0
    length=100
    x,y,index=0,0,0
    while index<10000:
        if length==0:
            break
        for i in range(length):
            newPx[(x+i*xStep,y+i*yStep)]=px[(index+i,0)]
        index+=length
        x+=xStep*(length-1)
        y+=yStep*(length-1)
        if xStep==1 or xStep==-1:
            hLines+=1
            length=100-hLines
        else:
            vLines+=1
            length=100-vLines
        if xStep==1:
            xStep=0
            yStep=1
        elif yStep==1:
            yStep=0
            xStep=-1
        elif xStep==-1:
            xStep=0
            yStep=-1
        elif yStep==-1:
            yStep=0
            xStep=1
    # wrong curve

    # for j in range(100):

    #     for i in range(100):

    #         newPx[(i,j)]=px[(j*100+i,0)]

    # newIm.save(path+"\\out.png")

    # newIm.show()

    return newIm

def spiral(source):
    px=source.load()
    target = Image.new(source.mode, (100, 100))
    targetPx = target.load()
    left, top, right, bottom = (0, 0, 99, 99)
    x, y = 0, 0
    dirx, diry = 1, 0
    for i in range(10000):
        # target.putpixel((x, y), source.getpixel((i, 0)))

        targetPx[(x,y)]=px[(i,0)]
        if dirx == 1 and x == right:
            dirx, diry = 0, 1
            top += 1
        elif dirx == -1 and x == left:
            dirx, diry = 0, -1
            bottom -= 1
        elif diry == 1 and y == bottom:
            dirx, diry = -1, 0
            right -= 1
        elif diry == -1 and y == top:
            dirx, diry = 1, 0
            left += 1
        x += dirx
        y += diry
    return target

# 与官方wiki中解法效率对比

# 使用*Image.load()得到像素数据,对此进行操作 比 使用*Image.getpixel和*Image.putpixel效率高

if __name__ == "__main__":
    # from timeit import Timer

    # t1=Timer("officialSolution()", "from __main__ import officialSolution")

    # t2=Timer("mySolution()", "from __main__ import mySolution")

    # print(t1.timeit(1000))

    # print(t2.timeit(1000))

    newIm=efficientSpiral(im)
    # newIm.save(path+"\\out.png")

    newIm.show()
    newIm.close()
    im.close()
PS src\static> python .\Code\Python\Challenge014.py

Challenge014.ps1

$path=".\\Data\\014"

. .\Code\PowerShell\helper.ps1
New-Dir -Dir $path

$wire="http://www.pythonchallenge.com/pc/return/wire.png"
$filename=$path+"\\wire.png"
Get-FileWithAuth -Url $wire -Filename $filename -Username "huge" -Password "file"

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$img=[System.Drawing.Image]::FromFile($filename)

$newImg=New-Object System.Drawing.Bitmap 100,100
$hLines,$vLines=0,0
$xStep,$yStep=1,0
$length=100
$x,$y,$index=0,0,0
while ($index -lt 10000) {
    if ($length -eq 0) {
        break
    }
    for ($i=0; $i -lt $length; $i++) {
        $newImg.SetPixel($x+$i*$xStep,$y+$i*$yStep, $img.GetPixel($index+$i,0))
    }
    $index+=$length
    $x+=$xStep*($length-1)
    $y+=$yStep*($length-1)
    if ($xStep -eq 1 -or $xStep -eq -1) {
        $hLines+=1
        $length=100-$hLines
    }
    else {
        $vLines+=1
        $length=100-$vLines
    }
    if ($xStep -eq 1) {
        $xStep=0
        $yStep=1
    }
    elseif ($yStep -eq 1) {
        $yStep=0
        $xStep=-1
    }
    elseif ($xStep -eq -1) {
        $xStep=0
        $yStep=-1
    }
    elseif ($yStep -eq -1) {
        $yStep=0
        $xStep=1
    }
}

Show-Image -Title "Challenge014" -Image $newImg -Width 300 -Height 200

# $img.Save($path+"\\cave.info.jpg")

$img.Dispose()
$newImg.Dispose()
PS src\static> .\Code\PowerShell\Challenge014.ps1

Challenge014.go

package main

import(
	"image"
)

func (c *Challenge) Challenge014() {
	path:=".\\Data\\014"
	EnsureDir(path)

	wire:="http://www.pythonchallenge.com/pc/return/wire.png"
	filename:=path+"\\wire.png"
	DownloadWithBasicAuth(wire, filename, "huge", "file")

	im:=OpenImage(filename)

	newImg:=efficientSpiral(im)

	pngfile := path+"\\wire.go.png"
	SaveImage(pngfile, newImg, "png")
	
	ShowImage(pngfile)
}

func efficientSpiral(im image.Image) *image.RGBA {
	newImg:=image.NewRGBA(image.Rect(0,0,100,100))
	hLines,vLines:=0,0
    xStep,yStep:=1,0
    length:=100
	x,y,index:=0,0,0
	for ; index < 10000; {
        if length==0 {
            break
		}
		for i := 0; i < length; i++ {
			newImg.Set(x+i*xStep,y+i*yStep,im.At(index+i,0))
		}
        index+=length
        x+=xStep*(length-1)
        y+=yStep*(length-1)
        if xStep==1 || xStep==-1 {
			hLines+=1
            length=100-hLines
		} else {
			vLines+=1
            length=100-vLines
		}

        if xStep==1 {
			xStep=0
            yStep=1
		} else if yStep==1 {
			yStep=0
            xStep=-1
		} else if xStep==-1 {
			xStep=0
            yStep=-1
		} else if yStep==-1 {
			yStep=0
			xStep=1
		}
	}

	return newImg
}
PS src\static> .\Code\Go\Challenge.exe -l 014

最终结果: uzi

[下一关地址][5]