Python Challenge Solutions Guide
Python Challenge Solutions Guide
of Contents
Introduction
1.1
Level 0
1.2
Level 1
1.3
Level 2
1.4
Level 3
1.5
Level 4
1.6
Level 5
1.7
Level 6
1.8
Level 7
1.9
Level 8
1.10
Level 9
1.11
Level 10
1.12
Level 11
1.13
Level 12
1.14
Level 13
1.15
Level 14
1.16
Level 15
1.17
Level 16
1.18
Level 17
1.19
Level 18
1.20
Level 19
1.21
Level 20
1.22
Level 21
1.23
Level 22
1.24
Level 23
1.25
Level 24
1.26
Level 25
1.27
Level 26
1.28
Level 27
1.29
Level 28
1.30
Level 29
1.31
Level 30
1.32
Level 31
1.33
Level 32
1.34
Level 33
1.35
Appendix: Links
1.36
Introduction
Learning Python
This eBook provides "just enough" knowledge for solving each challenge. To learn
more about Python, try these resources:
The Official Documentation: not always friendly for beginners, but it should be
treated as the single source of truth.
Books: books can be slightly outdated, however they may provide better entry
level tutorials, or dig deeper in a specific topic
Basics: Learning Python
More Advanced: Effective Python
Machine Learning: Python Machine Learning
Data Analysis: Python for Data Analysis
Data Visualization: Data Visualization with Python and JavaScript
Hacking: Black Hat Python
Web Scraping: Web Scraping with Python
HackingNote: last but not least, a shameless plug-in. I'm still learning Python,
and I'm taking notes and shaping my knowledge base along the way. Hope it
could help you as well.
Introduction
Level 0
Problem
Explore
As the "0" indicates, this is just a warm up.
Loop
The naive way to solve it: multiply by 2 in a loop:
Level 0
>>> k = 1
>>> for i in range(38):
... k *= 2
...
>>> k
274877906944
Power
Use ** for power:
>>> 2**38
274877906944
In REPL the result will be printed; or you can explicitly print the result by calling
print()
>>> print(2**38)
274877906944
or
>>> print(pow(2,38))
274877906944
Shift
Multiply by 2 is equivalent to shifting the binary representation left by one:
Level 0
>>> 1<<38
274877906944
Numeric Types
Done!
Wait, why 38? what is implied?
If you are coming from C/C++, Java or other languages, you know that there are
multiple types just for integers: short , integer , long , and even
BigInteger beyond 64-bit. However that is not the case in Python:
>>> type(2**3)
<class 'int'>
>>> type(2**38)
<class 'int'>
>>> type(2**380)
<class 'int'>
Complete Solution
print(2**38)
Output:
Level 0
274877906944
Next Level
[Link]
And it will jump to
[Link]
Read More
Python 3 - REPL
Level 1
Problem
Level 1
Hints
The text must be encoded.
Hint from url: map. And notice that there's exactly one character between the
given pairs: K->L->M , O->P->Q , E->F->G , and look at the very first letter in
the text g , if this is English, a good guess is that g is actually i . What is the
distance from g to i ? Yes, G->H->I . So let's shift each character to the
right, by 2, and y back to a , z back to b .
The string is not so long, so let's just copy and past it to REPL:
>>> raw = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amk
nsrcpq ypc dmp. bmgle grgl zw fylb gq glcddgagclr ylb rfyr'q ufw
rfgq rcvr gq qm jmle. sqgle [Link]() gq pcamkkclbcb.
lmu ynnjw ml rfc spj."
Solution 1
The pair of functions that would help up make the change:
ord() : character to integer
chr() : integer to character
e.g.
>>> chr(65)
'A'
>>> ord('A')
65
To shift a character:
10
Level 1
>>> ord('k')
107
>>> ord('k') + 2
109
>>> chr(ord('k') + 2)
'm'
11
Level 1
That is how we make a loop in Java or C, but python has a better way: list
comprehension
>>> ''.join([chr(((ord(s) + 2) - ord('a')) % 26 + ord('a')) if s
>= 'a' and s <= 'z' else s for s in raw])
"i hope you didnt translate it by hand. thats what computers are
for. doing itin by hand is inefficient and that's why this text
is so long. using [Link]() is recommended. now apply
on the url."
12
Level 1
Solution 2: .maketrans()
In Python 3, .maketrans is not in string as indicated; instead call
[Link]() or [Link]()
Solution 3
Let's have our own version of maketrans. The inputs are two lists, then each
character is mapped from one list to another.
Define the two lists
13
Level 1
zip them
>>> list(zip(a, b))
[('a', 'c'), ('b', 'd'), ('c', 'e'), ('d', 'f'), ('e', 'g'), ('f'
, 'h'), ('g', 'i'), ('h', 'j'), ('i', 'k'), ('j', 'l'), ('k', 'm'
), ('l', 'n'), ('m', 'o'), ('n', 'p'), ('o', 'q'), ('p', 'r'), (
'q', 's'), ('r', 't'), ('s', 'u'), ('t', 'v'), ('u', 'w'), ('v',
'x'), ('w', 'y'), ('x', 'z'), ('y', 'a'), ('z', 'b'), (',', ',')
, ('.', '.'), (' ', ' '), ("'", "'"), ('(', '('), (')', ')')]
14
Level 1
Next Level
As hinted, apply the same function on the url( map ), we get ocr .
>>> "map".translate([Link]("abcdefghijklmnopqrstuvwxyz",
"cdefghijklmnopqrstuvwxyzab"))
'ocr'
[Link]
Python 2 to Python 3
In Python 2, maketrans() is a method in string module, so you need to
import it first:
import string
table = [Link]("from", "to")
15
Level 1
16
Level 2
Problem
recognize the characters. maybe they are in the book, but MAYBE they are in
the page source.
Right click and select "View Page Source":
17
Level 2
Solution
Load Data
You can manually copy-and-paste the text to a file( resources/[Link] in
source code), then read from it:
>>> data = open('resources/[Link]').read()
Read More
More about Python 3 - IO
Or extract the text from HTML directly. First load raw html source coding using
[Link] :
18
Level 2
Then extract the comment blocks in html. Note that by default dot does not match
\n , so we need to use re .DOTALL flag.
>>> import re
>>> comments = [Link]("<!--(.*?)-->", html, [Link])
The pattern <!--(.*)--> will capture all blocks inside <!-- and --> . We
only care about the last part, so
>>> data = comments[-1]
Level 2
If you are having a hard time to guess the meaning:
>>> import re
>>> "".join([Link]("[A-Za-z]", data))
'equality'
result:
equality
Next Level
[Link]
20
Level 3
Problem
21
Level 3
Hmm, shall we find all segments of the pattern AAAbCCC ?
Solution
Step 1: Load Data
Similar to level 2, You can manually copy-and-paste the text to a
file( resources/[Link] in source code), then read from it:
>>> data = open('resources/[Link]').read()
22
Level 3
[^A-Z]+[A-Z]{3}([a-z])[A-Z]{3}[^A-Z]+ : ...and we only care about the
lower case
Let's see what we get:
>>> [Link]("[^A-Z]+[A-Z]{3}([a-z])[A-Z]{3}[^A-Z]+", data)
['l', 'i', 'n', 'k', 'e', 'd', 'l', 'i', 's', 't']
Next Level
[Link]
The page will redirect you to [Link]
[Link]
Further Readings
23
Level 3
Python 3 - RegEx
24
Level 4
Problem
Change the url with the new number and another number will be given.
Solution
25
Level 4
First let's try to mimic the manual process we just tried:
>>> uri = "[Link]
nothing=%s"
>>> num = "12345"
>>> content = urlopen(uri % num).read().decode()
>>> content
'and the next nothing is 44827'
Note .group(0) will return the whole text that matches the pattern, while the
captured segments start from .group (1)
>>> [Link](0)
'and the next nothing is 44827'
>>> [Link](1)
'72198'
To automate this process, let's use a while loop, which stops when there's no
match:
26
Level 4
And re-run:
and the next nothing is 81226
and the next nothing is 4256
and the next nothing is 62734
and the next nothing is 25666
...
There maybe misleading numbers in the
text. One example is 82683. Look only for the next nothing and t
he next nothing is 63579
...
[Link]
27
Level 4
Note that if you use [Link]() instead of [Link]() it would
fail, since .match() is looking for a match starting from the very beginning,
while there's one "misleading" line in the text.
Finally we have the answer: [Link]
Result
[Link]
Next Level
[Link]
Python 2 to Python 3
28
Level 4
Python 2's urllib and urllib2 are combined as the new urllib
29
Level 5
Problem
pronounce it
Page Source:
<peakhell src="banner.p"/>
<!-- peak hell sounds familiar ? -->
30
Level 5
Solution
Let's print out the raw data:
>>> from [Link] import urlopen
>>> raw = urlopen("[Link]
p").read()
>>> raw
b"(lp0\n(lp1\n(S' '\np2\nI95\ntp3\naa..."
Normally plain text can be encoded as utf-8 or some other form, once we call
.decode() it will reveal it self, however this one is tough:
>>> [Link]()
"(lp0\n(lp1\n(S' '\np2\nI95\ntp3\naa..."
31
Level 5
', 3), ('#', 4), (' ', 4), ('#', 5), (' ', 4), ('#', 4), (' ', 2
), ('#', 5), (' ', 4), ('#', 4), (' ', 3), ('#', 3), (' ', 5), (
'#', 3), (' ', 3), ('#', 4), (' ', 1)], [(' ', 1), ('#', 3), (' '
, 11), ('#', 4), (' ', 5), ('#', 4), (' ', 3), ('#', 3), (' ', 4
), ('#', 3), (' ', 4), ('#', 4), (' ', 5), ('#', 4), (' ', 2), (
'#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 3), (' ', 6), ('#',
4), (' ', 2), ('#', 4), (' ', 1)], [(' ', 1), ('#', 3), (' ', 11
), ('#', 4), (' ', 5), ('#', 4), (' ', 10), ('#', 3), (' ', 4), (
'#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 4), (' ', 5), ('#',
4), (' ', 2), ('#', 3), (' ', 7), ('#', 3), (' ', 2), ('#', 4), (
' ', 1)], [('#', 4), (' ', 11), ('#', 4), (' ', 5), ('#', 4), ('
', 5), ('#', 2), (' ', 3), ('#', 3), (' ', 4), ('#', 4), (' ', 5
), ('#', 4), (' ', 2), ('#', 4), (' ', 5), ('#', 4), (' ', 1), (
'#', 4), (' ', 7), ('#', 3), (' ', 2), ('#', 4), (' ', 1)], [('#'
, 4), (' ', 11), ('#', 4), (' ', 5), ('#', 4), (' ', 3), ('#', 10
), (' ', 4), ('#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 4), (
' ', 5), ('#', 4), (' ', 1), ('#', 14), (' ', 2), ('#', 4), (' '
, 1)], [('#', 4), (' ', 11), ('#', 4), (' ', 5), ('#', 4), (' ',
2), ('#', 3), (' ', 4), ('#', 4), (' ', 4), ('#', 4), (' ', 5), (
'#', 4), (' ', 2), ('#', 4), (' ', 5), ('#', 4), (' ', 1), ('#',
4), (' ', 12), ('#', 4), (' ', 1)], [('#', 4), (' ', 11), ('#', 4
), (' ', 5), ('#', 4), (' ', 1), ('#', 4), (' ', 5), ('#', 3), (
' ', 4), ('#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 4), (' ',
5), ('#', 4), (' ', 1), ('#', 4), (' ', 12), ('#', 4), (' ', 1)]
, [(' ', 1), ('#', 3), (' ', 11), ('#', 4), (' ', 5), ('#', 4), (
' ', 1), ('#', 4), (' ', 5), ('#', 3), (' ', 4), ('#', 4), (' ',
5), ('#', 4), (' ', 2), ('#', 4), (' ', 5), ('#', 4), (' ', 2), (
'#', 3), (' ', 12), ('#', 4), (' ', 1)], [(' ', 2), ('#', 3), ('
', 6), ('#', 2), (' ', 2), ('#', 4), (' ', 5), ('#', 4), (' ', 2
), ('#', 3), (' ', 4), ('#', 4), (' ', 4), ('#', 4), (' ', 5), (
'#', 4), (' ', 2), ('#', 4), (' ', 5), ('#', 4), (' ', 3), ('#',
3), (' ', 6), ('#', 2), (' ', 3), ('#', 4), (' ', 1)], [(' ', 3)
, ('#', 3), (' ', 4), ('#', 2), (' ', 3), ('#', 4), (' ', 5), ('
#', 4), (' ', 3), ('#', 11), (' ', 3), ('#', 4), (' ', 5), ('#',
4), (' ', 2), ('#', 4), (' ', 5), ('#', 4), (' ', 4), ('#', 3), (
' ', 4), ('#', 2), (' ', 4), ('#', 4), (' ', 1)], [(' ', 6), ('#'
, 3), (' ', 5), ('#', 6), (' ', 4), ('#', 5), (' ', 4), ('#', 2)
, (' ', 4), ('#', 4), (' ', 1), ('#', 6), (' ', 4), ('#', 11), (
' ', 4), ('#', 5), (' ', 6), ('#', 3), (' ', 6), ('#', 6)], [(' '
, 95)]]
32
Level 5
OK! So data is a list of lists of tuples... It does not look like a banner(the file
name), but more like the result of a simple string compression: convert the
repetitive characters to tuples of (character, number of appearance). This level is
all about serialization and compression, isn't it. Let's unravel the string:
>>> for line in data:
... print("".join([k * v for k, v in line]))
...
#####
#####
####
####
####
####
####
####
####
####
####
####
####
####
####
####
### #### ### ### ##### ### #####
### ### ####
### ## #### ####### ## ### #### ####### ####
####### ### ### ####
### ### ##### #### ### #### ##### #### ####
# #### ### ### ####
### #### #### ### ### #### #### ####
#### ### #### ####
### #### #### ### #### #### ####
#### ### ### ####
#### #### #### ## ### #### #### ####
#### #### ### ####
#### #### #### ########## #### #### ####
33
Level 5
#### ############## ####
#### #### #### ### #### #### #### ####
#### #### ####
#### #### #### #### ### #### #### ####
#### #### ####
### #### #### #### ### #### #### ####
#### ### ####
### ## #### #### ### #### #### #### ####
#### ### ## ####
### ## #### #### ########### #### #### ####
#### ### ## ####
### ###### ##### ## #### ###### ##########
# ##### ### ######
`
Next Level
[Link]
34
Level 6
Problem
Ok... the image was about "zip", not "pants" or anything under it...
Replace html with zip : [Link]
35
Level 6
Unzip it. In [Link]:
welcome to my zipped list.
hint1: start from 90052
hint2: answer is inside the zip
Solution
>>> import zipfile, re
>>>
>>> f = [Link]("resources/[Link]")
>>> num = '90052'
>>> while True:
... content = [Link](num + ".txt").decode("utf-8")
... print(content)
... match = [Link]("Next nothing is (\d+)", content)
... if match == None:
... break
... num = [Link](1)
...
Next nothing is 94191
Next nothing is 85503
Next nothing is 70877
...
Next nothing is 68628
Next nothing is 67824
Next nothing is 46145
Collect the comments.
Level 6
Add a few lines to collect the comments:
>>> num = '90052'
>>> comments = []
>>> while True:
... content = [Link](num + ".txt").decode("utf-8")
... [Link]([Link](num + ".txt").[Link]("
utf-8"))
... content
... match = [Link]("Next nothing is (\d+)", content)
... if match == None:
... break
... num = [Link](1)
...
>>> print("".join(comments))
****************************************************************
****************************************************************
** **
** OO OO XX YYYY GG GG EEEEEE NN NN **
** OO OO XXXXXX YYYYYY GG GG EEEEEE NN NN **
** OO OO XXX XXX YYY YY GG GG EE NN NN **
** OOOOOOOO XX XX YY GGG EEEEE NNNN **
** OOOOOOOO XX XX YY GGG EEEEE NN **
** OO OO XXX XXX YYY YY GG GG EE NN **
** OO OO XXXXXX YYYYYY GG GG EEEEEE NN **
** OO OO XX YYYY GG GG EEEEEE NN **
** **
****************************************************************
**************************************************************
Level 6
import zipfile, re
f = [Link]("[Link]")
print([Link]("[Link]").decode("utf-8"))
num = '90052'
comments = []
while True:
content = [Link](num + ".txt").decode("utf-8")
[Link]([Link](num + ".txt").[Link]("utf8"))
print(content)
match = [Link]("Next nothing is (\d+)", content)
if match == None:
break
num = [Link](1)
print("".join(comments))
Next Level
[Link]
38
Level 7
Problem
Solution 1: PIL(Pillow)
Python 2 to 3
The original PIL was not ported to Python 3. Use the fork called ``Pillow``
instead
Install Pillow
$ pip3 install pillow
To load an image, one way is to download the image to local manually, then load it
by:
39
Level 7
As you can tell, row has lots of duplicates, since each grey block's width is larger
than 1 pixel. If you do some manual counting, you know it is exactly 7 pixels wide,
this should be the easiest way to de-dup:
40
Level 7
Notice that at the end of the array there are some noises: pixels that are not grey
scale, which have the same value for R, G, and B. We can remove those pixels
>>> ords = [r for r, g, b, a in row if r == g == b]
and since RGB is using a positive number in [0, 255] for each color, we can
assume it represents a ASCII character:
>>> "".join(map(chr, ords))
'smart guy, you made it. the next level is [105, 110, 116, 101,
103, 114, 105, 116, 121]'
Finally:
>>> "".join(map(chr, map(int, nums)))
'integrity'
Solution 2: PyPNG
Alternatively use a package called PyPNG :
pip install pypng
41
Level 7
Next Level
[Link]
42
Level 7
Read More
Pillow Documentation
43
Level 8
Problem
44
Level 8
<!-un: 'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00 \
x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
pw: 'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x03$ \x00!\x9ah3M\
x13<]\xc9\x14\xe1BBP\x91\xf08'
-->
The opposite of "inflate" is... "compress". Do not blame yourself if you do not know
which compression format it is. Here are some clues that it is "bzip2"...
.magic:16 = 'BZ' signature/magic number .version:8 = 'h' for Bzip2 ('H'uffman
coding), '0' for Bzip1 (deprecated) .hundred_k_blocksize:8 = '1'..'9' block-size
100 kB-900 kB (uncompressed)
Solution
Let's decompress it:
>>> import bz2
>>> [Link]('BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x0
2\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/[Link]", line 348, in decompress
res = [Link](data)
TypeError: a bytes-like object is required, not 'str'
That does not work... .decompress() expects some bytes , not string
>>> [Link](b'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x
02\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084')
b'huge'
>>> [Link](b'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x0
3$ \x00!\x9ah3M\x13<]\xc9\x14\xe1BBP\x91\xf08')
b'file'
45
Level 8
Next Level
Click the fly(or the link in page source): ../return/[Link] , and fill in
username( huge ) and password( file )
[Link]
46
Level 9
Problem
In page source:
<!-first+second=?
first:
146,399,163,403,170,393,169,391,166,386,170,381,170,371,170,355,
169,346,167,335,170,329,170,320,170,
47
Level 9
310,171,301,173,290,178,289,182,287,188,286,190,286,192,291,194,
296,195,305,194,307,191,312,190,316,
190,321,192,331,193,338,196,341,197,346,199,352,198,360,197,366,
197,373,196,380,197,383,196,387,192,
389,191,392,190,396,189,400,194,401,201,402,208,403,213,402,216,
401,219,397,219,393,216,390,215,385,
215,379,213,373,213,365,212,360,210,353,210,347,212,338,213,329,
214,319,215,311,215,306,216,296,218,
290,221,283,225,282,233,284,238,287,243,290,250,291,255,294,261,
293,265,291,271,291,273,289,278,287,
279,285,281,280,284,278,284,276,287,277,289,283,291,286,294,291,
296,295,299,300,301,304,304,320,305,
327,306,332,307,341,306,349,303,354,301,364,301,371,297,375,292,
384,291,386,302,393,324,391,333,387,
328,375,329,367,329,353,330,341,331,328,336,319,338,310,341,304,
341,285,341,278,343,269,344,262,346,
259,346,251,349,259,349,264,349,273,349,280,349,288,349,295,349,
298,354,293,356,286,354,279,352,268,
352,257,351,249,350,234,351,211,352,197,354,185,353,171,351,154,
348,147,342,137,339,132,330,122,327,
120,314,116,304,117,293,118,284,118,281,122,275,128,265,129,257,
131,244,133,239,134,228,136,221,137,
214,138,209,135,201,132,192,130,184,131,175,129,170,131,159,134,
157,134,160,130,170,125,176,114,176,
102,173,103,172,108,171,111,163,115,156,116,149,117,142,116,136,
115,129,115,124,115,120,115,115,117,
113,120,109,122,102,122,100,121,95,121,89,115,87,110,82,109,84,1
18,89,123,93,129,100,130,108,132,110,
133,110,136,107,138,105,140,95,138,86,141,79,149,77,155,81,162,9
0,165,97,167,99,171,109,171,107,161,
111,156,113,170,115,185,118,208,117,223,121,239,128,251,133,259,
136,266,139,276,143,290,148,310,151,
332,155,348,156,353,153,366,149,379,147,394,146,399
second:
156,141,165,135,169,131,176,130,187,134,191,140,191,146,186,150,
179,155,175,157,168,157,163,157,159,
157,158,164,159,175,159,181,157,191,154,197,153,205,153,210,152,
212,147,215,146,218,143,220,132,220,
125,217,119,209,116,196,115,185,114,172,114,167,112,161,109,165,
48
Level 9
107,170,99,171,97,167,89,164,81,162,
77,155,81,148,87,140,96,138,105,141,110,136,111,126,113,129,118,
117,128,114,137,115,146,114,155,115,
158,121,157,128,156,134,157,136,156,136
-->
first and second have different lengths, so it is not simply adding up the two
arrays. The image has some dots, maybe we should just connect the dots...
Solution
Copy and paste...
>>> first = [
... 146,399,163,403,170,393,169,391,166,386,170,381,170,371,170,
355,169,346,167,335,170,329,170,320,170,
... 310,171,301,173,290,178,289,182,287,188,286,190,286,192,291,
194,296,195,305,194,307,191,312,190,316,
... 190,321,192,331,193,338,196,341,197,346,199,352,198,360,197,
366,197,373,196,380,197,383,196,387,192,
... 389,191,392,190,396,189,400,194,401,201,402,208,403,213,402,
216,401,219,397,219,393,216,390,215,385,
... 215,379,213,373,213,365,212,360,210,353,210,347,212,338,213,
329,214,319,215,311,215,306,216,296,218,
... 290,221,283,225,282,233,284,238,287,243,290,250,291,255,294,
261,293,265,291,271,291,273,289,278,287,
... 279,285,281,280,284,278,284,276,287,277,289,283,291,286,294,
291,296,295,299,300,301,304,304,320,305,
... 327,306,332,307,341,306,349,303,354,301,364,301,371,297,375,
292,384,291,386,302,393,324,391,333,387,
... 328,375,329,367,329,353,330,341,331,328,336,319,338,310,341,
304,341,285,341,278,343,269,344,262,346,
... 259,346,251,349,259,349,264,349,273,349,280,349,288,349,295,
349,298,354,293,356,286,354,279,352,268,
... 352,257,351,249,350,234,351,211,352,197,354,185,353,171,351,
154,348,147,342,137,339,132,330,122,327,
... 120,314,116,304,117,293,118,284,118,281,122,275,128,265,129,
49
Level 9
257,131,244,133,239,134,228,136,221,137,
... 214,138,209,135,201,132,192,130,184,131,175,129,170,131,159,
134,157,134,160,130,170,125,176,114,176,
... 102,173,103,172,108,171,111,163,115,156,116,149,117,142,116,
136,115,129,115,124,115,120,115,115,117,
... 113,120,109,122,102,122,100,121,95,121,89,115,87,110,82,109,
84,118,89,123,93,129,100,130,108,132,110,
... 133,110,136,107,138,105,140,95,138,86,141,79,149,77,155,81,1
62,90,165,97,167,99,171,109,171,107,161,
... 111,156,113,170,115,185,118,208,117,223,121,239,128,251,133,
259,136,266,139,276,143,290,148,310,151,
... 332,155,348,156,353,153,366,149,379,147,394,146,399]
>>> second = [156,141,165,135,169,131,176,130,187,134,191,140,191
,146,186,150,179,155,175,157,168,157,163,157,159,
... 157,158,164,159,175,159,181,157,191,154,197,153,205,153,210,
152,212,147,215,146,218,143,220,132,220,
... 125,217,119,209,116,196,115,185,114,172,114,167,112,161,109,
165,107,170,99,171,97,167,89,164,81,162,
... 77,155,81,148,87,140,96,138,105,141,110,136,111,126,113,129,
118,117,128,114,137,115,146,114,155,115,
... 158,121,157,128,156,134,157,136,156,136]
Use PIL(pillow)
>>> from PIL import Image,ImageDraw
>>> im = [Link]('RGB', (500,500))
>>> draw = [Link](im)
>>> [Link](first, fill='white')
>>> [Link](second, fill='white')
>>> [Link]()
50
Level 9
Next Level
[Link]
51
Level 10
Problem
len(a[30]) = ?
By clicking the image:
a = [1, 11, 21, 1211, 111221,
A look-and-say sequence
52
Level 10
Solution 1
This is a naive solution, just look, and say, assemble the string while we are
counting.
a = '1'
b = ''
for i in range(0, 30):
j = 0
k = 0
while j < len(a):
while k < len(a) and a[k] == a[j]: k += 1
b += str(k-j) + a[j]
j = k
print b
a = b
b = ''
print len(a)
Solution 2
Python can do much better. We can use regular expression to find the (number,
length) pairs
>>> import re
>>> [Link](r"(\d)(\1*)", "111221")
[('1', '11'), ('2', '2'), ('1', '')]
Note that the pattern is a raw string( r"..." ), which means backslash( \ ) does
not need to be escaped. It is equivalent to
>>> [Link]("(\\d)(\\1*)", "111221")
The result tuples are in the form: (first appearance, following appearance), so from
the first one we get the number, and the second one we get the length(remember
to +1)
53
Level 10
Solution 3
Similar to Solution 2, but we are using [Link]() instead of regular
expression to find the (number, length) pairs:
>>> "".join([str(len(list(j))) + i for i,j in [Link](
"1211")])
'111221'
54
Level 10
Solution 4
This is not recommend, but it is a cool one-liner solution. Do not sacrifice clarity
for coolness in the real world projects!
>>> from itertools import groupby
>>> from functools import reduce
>>> len(reduce(lambda x, n:reduce(lambda a, b: a + str(len(list(
b[1]))) + b[0], groupby(x), ""), range(30), "1"))
5808
2 nested reduce() , the outer one simply let it run for 30 times, and set the initial
value 1 for x ; the inner one does exactly the same as in Solution 3.
Again, whether this bothers you or not, do not code anything that need you
extensive explanations.
Next Level
[Link]
55
Level 10
56
Level 11
Problem
Solution
The only clue is the title, which implies that we need to split the image by
odd/even:
57
Level 11
Next Level
[Link]
58
Level 12
Problem
Checking the source, the image is named as [Link] . Try evil2 and you
will see:
[Link]
59
Level 12
60
Level 12
Really? "no more evils"? Let's try [Link]. Depend on your browser, you may see
nothing or an error message
The image "[Link] cannot be
displayed because it contains errors.
But, it is not 404! Let's take a closer look:
$ curl -u huge:file [Link]
[Link]
Bert is evil! go back!
Solution
It is hard to tell what's going on inside the file.
61
Level 12
Back to the problem's image, someone is dealing the cards into 5 stacks, and all
the cards are ... 5.
>>> len(data)
67575
Let's try to split the data into 5, but "dealing" the bytes instead of cards...
>>> for i in range(5):
... open('%[Link]' % i ,'wb').write(data[i::5])
Open the generated [Link] through [Link] , you should see dis , pro ,
port , tional
62
Level 12
63
Level 12
Next Level
[Link]
64
Level 13
Problem
65
Level 13
<methodResponse>
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value>
<int>105</int>
</value>
</member>
<member>
<name>faultString</name>
<value>
<string>
XML error: Invalid document end at line 1, column
1
</string>
</value>
</member>
</struct>
</value>
</fault>
</methodResponse>
Solution
We can use xmlrpc module to talk to it:
>>> import [Link]
>>> conn = [Link]("[Link]
.com/pc/[Link]")
>>> conn
<ServerProxy for [Link]/pc/[Link]>
>>> [Link]()
['phone', '[Link]', '[Link]', '[Link]
hodSignature', '[Link]', '[Link]']
66
Level 13
phone seems to be the method we should call. Get more info on how to use it:
>>> [Link]("phone")
'Returns the phone of a person'
>>> [Link]("phone")
[['string', 'string']]
So it takes a string and returns a string, the input should be the name and the
output should be the number:
>>> [Link]("Bert")
'555-ITALY'
If you do not know, 555 basically means "fake phone numbers" in US... The key
is "italy".
Next Level
[Link]
67
Level 14
Problem Link
[Link]
Username: huge
Password: file
Clues
Clue 1
In HTML source code:
68
Level 14
Clue 2
Title of the HTML:
walk around
Clue 3
The image of the problem: we are looking at(for) something spiral!
Exploration
Do not be fooled by that barcode-like image, it appears to be a square, that is
because in HTML both the width and height are set as 100.
>>> from PIL import Image
>>> im = [Link]('../images/[Link]')
>>> [Link]
(10000, 1)
69
Level 14
Solution
from PIL import Image
im = [Link]('[Link]')
delta = [(1,0),(0,1),(-1,0),(0,-1)]
out = [Link]('RGB', [100,100])
x,y,p = -1,0,0
d = 200
while d/2>0:
for v in delta:
steps = d // 2
for s in range(steps):
x, y = x + v[0], y + v[1]
[Link]((x, y),[Link]((p,0)))
p += 1
d -= 1
[Link]('level_14_result.jpg')
It's a cat!
Next Level
[Link]
and its name is uzi. you'll hear from him later.
[Link]
70
Level 15
Problem Link
Link: [Link]
Username: huge
Password: file
Clues
Clue 1
There's a burnt hole on the calendar, it must be year 1xx6.
71
Level 15
Clue 2
That year's Jan 1 is a Thursday.
Clue 3
It was a leap year, since Feb 29 is on the calendar.
Clue 4
We are looking for Jan 26.
Clue 5
In HTML source code:
<!-- he ain't the youngest, he is the second -->
Clue 6
Title: whom?
Clue 7
In HTML source code:
<!-- todo: buy flowers for tomorrow -->
Exploration
So we are looking for a person, who's related to that particular date, and he is not
the youngest...
The key is to find what year it was. We can filter the years between 1006 and
1996 by those clues.
72
Level 15
First the leap year. Is 1006 a leap year?
>>> 1006 / 4
251.5
From clue 5:
he ain't the youngest, he is the second
1976 must be the youngest, so 1756 is the second youngest... what is special with
1756-01-26? Nothing. But remember the last clue:
todo: buy flowers for tomorrow
And... 1756-01-27 is the birthday of Mozart...
73
Level 15
Solution
Alternatively we can use [Link]() to detect leap year, which
makes it more clear. Check out the full solution:
import datetime, calendar
for year in range(1006,1996,10):
d = [Link](year, 1, 26)
if [Link]() == 1 & [Link](year):
print(d)
Output
1176-01-26
1356-01-26
1576-01-26
1756-01-26
1976-01-26
Next Level
[Link]
74
Level 16
Problem Link
Link: [Link]
Username: huge
Password: file
Clues
Clue 1
Page Title:
let me get this straight
75
Level 16
Clue 2
Image: There are pink segments, looks like they have the same length.
Exploration
Sounds like we need to align the pink segments. But how do you define "pink"
So value 60 appears 29448 times, let's see if it is pink. We can make a copy of the
current image(to use the same palette), and paint all the pixels as 60:
>>> tmp = [Link]()
>>> [Link](bytes([60] * ([Link] * [Link])))
>>> [Link]()
76
Level 16
77
Level 16
We are using [Link](image) to load image data, alternatively you can use
list([Link]()) , however you will get a one-dimension array, so you
78
Level 16
Solution
Solution 1
from PIL import Image, ImageChops
import numpy as np
image = [Link]("[Link]")
shifted = [bytes([Link](row, -[Link]().index(195)).tolist()
) for row in [Link](image)]
[Link]([Link], [Link], b"".join(shifted)).show(
)
79
Level 16
Solution 2
from PIL import Image, ImageChops
image = [Link]("[Link]")
for y in range([Link][1]):
box = 0, y, [Link][0], y + 1
row = [Link](box)
bytes = [Link]()
i = [Link](195)
row = [Link](row, -i)
[Link](row, box)
[Link]("[Link]")
Result: romance!
Next Level
[Link]
80
Level 17
Problem Link
Link: [Link]
Username: huge
Password: file
Clues
Clue 1
Image: it is named cookies
Clue 2
81
Level 17
There's an embedded image. Looks familiar? It's from Level 4.
Solution
Part 1:
from [Link] import urlopen
from [Link] import unquote_plus, unquote_to_bytes
import re, bz2
num = '12345'
info = ''
while(True):
h = urlopen('[Link]
[Link]?busynothing='+num)
raw = [Link]().decode("utf-8")
print(raw)
cookie = [Link]("Set-Cookie")
info += [Link]('info=(.*?);', cookie).group(1)
match = [Link]('the next busynothing is (\d+)', raw)
if match == None:
break
else:
num = [Link](1)
res = unquote_to_bytes([Link]("+", " "))
print(res)
print([Link](res).decode())
Output:
82
Level 17
...
and the next busynothing is 96070
and the next busynothing is 83051
that's it.
b'BZh91AY&SY\x94:\xe2I\x00\x00!\x19\x80P\x81\x11\x00\xafg\x9e\xa
0 \x00hE=M\xb5#\xd0\xd4\xd1\xe2\x8d\x06\xa9\xfa&S\xd4\xd3!\xa1\x
eai7h\x9b\x9a+\xbf`"\xc5WX\xe1\xadL\x80\xe8V<\xc6\xa8\xdbH&32\x1
8\xa8x\x01\x08!\x8dS\x0b\xc8\xaf\x96KO\xca2\xb0\xf1\xbd\x1du\xa0
\x86\x05\x92s\xb0\x92\xc4Bc\xf1w$S\x85\t\tC\xae$\x90'
Part 2:
from [Link] import ServerProxy
conn = ServerProxy("[Link]
php")
print([Link]("Leopold"))
555-VIOLIN
Visit [Link]
no! i mean yes! but ../stuff/[Link].
Part 3:
83
Level 17
<html>
<head>
<title>it's me. what do you want?</title>
<link rel="stylesheet" type="text/css" href="../[Link]">
</head>
<body>
<br><br>
<center><font color="gold">
<img src="[Link]" border="0"/>
<br><br>
oh well, don't you dare to forget the balloons.</font>
</body>
</html>
Next Level
[Link]
redirect to
[Link]
84
Level 18
Problem
Solution
The difference is "brightness"... so go to
[Link]
In HTML source:
<!-- maybe consider [Link] -->
Download: [Link]
>>> print([Link]("[Link]").read().decode())
85
Level 18
You will see the data consists roughly two columns.
import gzip, difflib
data = [Link]("[Link]")
d1, d2 = [], []
for line in data:
[Link](line[:53].decode()+"\n")
[Link](line[56:].decode())
86
Level 18
[Link] : butter
[Link] : fly
Next Level
[Link]
username: butter
password: fly
87
Level 19
Problem
Solution
88
Level 19
w = [Link]('[Link]', 'rb')
h = [Link]("[Link]", "wb")
print([Link]())
print([Link]())
print([Link]())
[Link]([Link]())
[Link]([Link]()//2)
[Link]([Link]()*2)
frames = [Link]([Link]())
wave.big_endiana = 1
[Link](frames)
[Link]()
Next Level
[Link]
89
Level 20
Problem
Solution
90
Level 20
91
Level 20
So now the content between 30203 and 30236 is served, which is "Why don't you
respect my privacy?"; continue for a few iterations:
pattern = [Link]('bytes (\d+)-(\d+)/(\d+)')
content_range = [Link]['content-range']
(start, end, length) = [Link](content_range).groups()
while True:
try:
[Link]['Range'] = 'bytes=%i-' % (int(end) + 1)
response = [Link](request)
print([Link]().decode())
print([Link])
(start, end, length) = [Link]([Link]['
content-range']).groups()
except:
break
It prints:
Why don't you respect my privacy?
we can go on in this way for really long time.
stop this!
invader! invader!
ok, invader. you are inside now.
92
Level 20
Result:
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-Range: bytes 2123456744-2123456788/2123456789
Connection: close
Transfer-Encoding: chunked
Server: lighttpd/1.4.35
esrever ni emankcin wen ruoy si drowssap eht
The content is reversed: "the password is your new nickname in reverse". The
"nickname" is "invader", so password is "redavni".
Now "reverse" the search:
[Link]['Range'] = 'bytes=2123456743-'
response = [Link](request)
print([Link])
print([Link]().decode())
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-Range: bytes 2123456712-2123456743/2123456789
Connection: close
Transfer-Encoding: chunked
Date: Mon, 02 May 2016 18:12:45 GMT
Server: lighttpd/1.4.35
93
Level 20
Then save it as a zip file:
[Link]['Range'] = 'bytes=1152983631-'
response = [Link](request)
with open("[Link]", "wb") as f:
[Link]([Link]())
Next Level
Inside the zip file
94
Level 21
Solution
import zlib, bz2
with open("[Link]", "rb") as f:
data = [Link]()
while True:
if [Link](b'x\x9c'):
data = [Link](data)
elif [Link](b'BZh'):
data = [Link](data)
elif [Link](b'\x9cx'):
data = data[::-1]
else:
break
print(data)
Result:
b'sgol ruoy ta kool'
Add logging:
95
Level 21
96
Level 21
Next Level
[Link]
97
Level 22
Problem
Solution
98
Level 22
Result: bonus
Next Level
[Link]
99
Level 23
Problem
Solution
this is a special module in Python:
100
Level 23
101
Level 23
>>> print(this.s)
Gur Mra bs Clguba, ol Gvz Crgref
Ornhgvshy vf orggre guna htyl.
Rkcyvpvg vf orggre guna vzcyvpvg.
Fvzcyr vf orggre guna pbzcyrk.
Pbzcyrk vf orggre guna pbzcyvpngrq.
Syng vf orggre guna arfgrq.
Fcnefr vf orggre guna qrafr.
Ernqnovyvgl pbhagf.
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
Nygubhtu cenpgvpnyvgl orngf chevgl.
Reebef fubhyq arire cnff fvyragyl.
Hayrff rkcyvpvgyl fvyraprq.
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb q
b vg.
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgp
u.
Abj vf orggre guna arire.
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!
102
Level 23
103
Level 23
>>> this.d
{'n': 'a', 'J': 'W', 'o': 'b', 'r': 'e', 'T': 'G', 'K': 'X', 'v'
: 'i', 'H': 'U', 'L': 'Y', 'q': 'd', 'w': 'j', 'O': 'B', 'e': 'r'
, 'S': 'F', 'l': 'y', 'X': 'K', 'I': 'V', 'a': 'n', 'Z': 'M', 'G'
: 'T', 'i': 'v', 'f': 's', 'u': 'h', 'h': 'u', 'N': 'A', 'R': 'E'
, 'P': 'C', 'M': 'Z', 'C': 'P', 'b': 'o', 'U': 'H', 'A': 'N', 'B'
: 'O', 'W': 'J', 'D': 'Q', 'k': 'x', 'c': 'p', 'x': 'k', 'm': 'z'
, 'F': 'S', 'V': 'I', 'E': 'R', 'Q': 'D', 'p': 'c', 'g': 't', 'Y'
: 'L', 'j': 'w', 'y': 'l', 's': 'f', 't': 'g', 'z': 'm', 'd': 'q'
}
104
Level 23
Use this to decode the message:
>>> s = 'va gur snpr bs jung?'
>>> print("".join([[Link](c, c) for c in s]))
in the face of what?
Next Level
[Link]
105
Level 24
Problem
Solution
106
Level 24
Load the image:
>>> from PIL import Image
>>> maze = [Link]("[Link]")
>>> w, h = [Link]
There's only one black pixel( (0, 0, 0, 255) ), others are white( (255, 255,
255, 255) ) or grey(the upper left corner square with the number of the level), so
there's only one black pixel at (1, h - 1) , that would be the exit point.
By printing out the "inner" pixels you may notice that the non-white points all look
like (x, 0, 0, 255) , where x would vary. That is the data we need to
collect.
A BFS would find the shortest path:
107
Level 24
Next Level
[Link]
108
Level 24
109
Level 25
Problem
Solution
To download a wav file, use wget with authentication:
$ wget --user butter --password fly
[Link]
To download all the wav files:
110
Level 25
Next Level
[Link]/pc/hex/[Link]
111
Level 26
Problem
Solution
Send the email to [Link]@[Link] and get the response:
112
Level 26
From: [Link]@[Link] Subject: Re: sorry Date:
Never mind that.
Have you found my broken zip?
md5: bbb8b499a0eef99b52c7f13f4e78c24b
Can you believe what one mistake can lead to?
As indicated there's only "one mistake". Try to modify the data and check by md5
code.
import hashlib
def search_and_save():
for i in range(len(data)):
for j in range(256):
newData = data[:i] + bytes([j]) + data[i + 1:]
if hashlib.md5(newData).hexdigest() == md5code:
open('[Link]', 'wb').write(newData)
return
md5code = 'bbb8b499a0eef99b52c7f13f4e78c24b'
data = open('maze/[Link]', 'rb').read()
search_and_save()
Next Level
[Link]
Python 2 to 3
md5 module is deprecated, use hashlib.md5()
113
Level 26
open() without explicitly specifying rb will use the default utf-8 codec
for decoding.
114
Level 27
Problem
Solution
115
Level 27
Full Solution
116
Level 27
palette = [Link]()[::3]
table = [Link](bytes([i for i in range(256)]), bytes(pa
lette))
raw = [Link]()
trans = [Link](table)
zipped = list(zip(raw[1:], trans[:-1]))
diff = list(filter(lambda p: p[0] != p[1], zipped))
indices = [i for i,p in enumerate(zipped) if p[0] != p[1]]
im2 = [Link]("RGB", [Link])
colors = [(255, 255, 255)] * len(raw)
for i in indices:
colors[i] = (0, 0, 0)
[Link](colors)
#[Link]()
Result:
117
Level 27
Well, this level needs to be updated, since exec and print are not keywords
in Python 3. The only two words left are repeat and switch
Next Level
[Link]
username: repeat
password: switch
118
Level 28
Problem
Solution
[Link]
yes! green!
119
Level 28
Result
whodunnit().split()[0] ?
The creator of Python is Guido van Rossum, so the final answer is "guido"
Next Level
[Link]
120
Level 29
Problem
Solution
Notice that there "silent" empty lines in the html source code. And the lines are of
different lengths. Convert the lengths to bytes and decompress by bz2:
121
Level 29
Next Level
[Link]
122
Level 30
Problem
Solution
$ wget --user repeat --password switch
[Link]
123
Level 30
keyword: grandpa
Next Level
124
Level 30
[Link]
125
Level 31
Problem
126
Level 31
127
Level 31
In page source:
<img src="[Link]" border="0">
<window left="0.34" top="0.57" width="0.036" height="0.027"/>
<option iterations="128"/>
Solution
It is a image of the Mandelbrot set.
The Mandelbrot set is the set of complex numbers c for which the function f(z)
= z^2 + c does not diverge when iterated from z = 0, i.e., for which the
sequence f(0), f(f(0)), etc., remains bounded in absolute value.
To slightly translate this into English: every pixel in the 2-d image (x, y) ,
uniquely represents a complex number c , we let z = 0 + 0j , then repeatedly
calculate z = z * z + c , if z is always within a range(not going to infinity),
128
Level 31
we light this pixel up, otherwise we mark it as dark. Actually we check at which
iteration it starts to diverge, and set color to that number of iteration.
In page source we are given 4 number: left, top, width, height, that is the bound of
our calculation. Suppose the image we are going to produce has width w and
height h , then x should be from 0 to w - 1 , and y should be from 0
to h - 1 . The real part of the c can be computed by left + x * width /
w , and imaginary part is bottom + y * height / h
129
Level 31
Extra Links
[Link]
130
Level 32
Problem
Solution
131
Level 32
import time
class Seg:
def __init__(self, length):
[Link] = length
[Link] = []
def __repr__(self):
return '<Seg:len=' + str([Link]) + ',placements=' +
str([Link]) + '>'
class Bar:
def __init__(self, axis, index, segs, length):
[Link] = segs
[Link] = False
[Link] = False
[Link] = axis
[Link] = index
[Link] = length
self.full_space = sum([[Link] for seg in [Link]])
+ len([Link]) - 1
def is_full(self):
return self.full_space == [Link]
def __repr__(self):
return '<Bar:axis=' + str([Link]) + ',index=' + str(s
[Link]) + ',len=' + str(
[Link]) + ',full_space=' + str(
self.full_space) + ',segs=' + str([Link]) + ',dir
ty=' + str([Link]) + '>'
def __lt__(self, other):
return [Link] - [Link]
def load():
132
Level 32
with open("[Link]") as f:
lines = [Link]()
lines = [[Link]() for line in lines if (not [Link]
rtswith('#')) and len([Link]()) != 0]
raw = [list(map(int, [Link]())) for line in lines]
assert sum(raw[0]) == len(raw) - 1
return raw[1:raw[0][0] + 1], raw[raw[0][0] + 1:]
def print_board(board):
m = {1: '#', 0: ' ', None: '?'}
print("\n".join([''.join([m[ele] for ele in row]) for row in
board]))
def calc_space(segs):
return sum([[Link] for seg in segs]) + len(segs) - 1
def calc_placement(bars):
for bar in bars:
for i in range(len([Link])):
seg = [Link][i]
start = calc_space([Link][:i]) + 1
end = [Link] - calc_space([Link][i + 1:]) - se
[Link]
[Link] = list(range(start, end))
133
Level 32
for seg in [Link]:
for i in range([Link][-1], [Link][0]
+ [Link]):
if update_board(board, bar, i, 1):
bars[(1 - [Link]) * h + i].dirty = True
134
Level 32
end = len(board[[Link]][0])
if i != len(tmp_placements) - 1:
end = tmp_placements[i + 1]
for j in range(placement + [Link], end):
flags[j] |= 2
prev = placement + [Link]
135
Level 32
check_bar(board, bar, start=placement + [Link] +
1, iseg=iseg + 1, tmp_placements=tmp_placements,
flags=flags)
136
Level 32
ags=flags)
for i in range(len(flags)):
flag = flags[i]
if flag == 1:
if update_board(board, bar, i, 1):
bars[(1 - [Link]) * h + i].dirty = True
elif flag == 2:
if update_board(board, bar, i, 0):
bars[(1 - [Link]) * h + i].dirty = True
[Link] = False
print_board(board[0])
print(time.process_time())
Next Level
Level 33: [Link]
137
Level 33
Problem
Solution
>>> [Link]
(138, 138)
>>> [Link]
'L'
>>> list([Link]())
[1, 43, 7, 13, 7, 1, 1, 85, 25, 85,...]
>>> [Link]()
[0, 1532, 232, 0, 0, 0, 0, 963, 189, 0, 0, 0, 0, 724, 329, 0, 0,
0, 0, 549, 243, 0, 0, 0, 0, 144, 424, 0, 0, 0, 0, 119, 328, 0, 0
138
Level 33
, 0, 0, 126, 339, 0, 0, 0, 0, 126, 357, 0, 0, 0, 0, 107, 225, 0,
0, 0, 0, 79, 609, 0, 0, 0, 0, 181, 356, 0, 0, 0, 0, 70, 298, 0, 0
, 0, 0, 23, 164, 0, 0, 0, 0, 26, 354, 0, 0, 0, 0, 47, 341, 0, 0,
0, 0, 139, 257, 0, 0, 0, 0, 104, 505, 0, 0, 0, 0, 192, 224, 0, 0
, 0, 0, 114, 310, 0, 0, 0, 0, 32, 183, 0, 0, 0, 0, 238, 198, 0, 0
, 0, 0, 117, 327, 0, 0, 0, 0, 110, 342, 0, 0, 0, 0, 118, 342, 0,
0, 0, 0, 145, 323, 0, 0, 0, 0, 152, 324, 0, 0, 0, 0, 161, 323, 0
, 0, 0, 0, 175, 317, 0, 0, 0, 0, 183, 317, 0, 0, 0, 0, 171, 337,
0, 0, 0, 0, 198, 318, 0, 0, 0, 0, 241, 283, 0, 0, 0, 0, 1348, 272
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> list(enumerate([Link]()))
[(0, 0), (1, 1532), (2, 232), (3, 0), (4, 0), (5, 0), (6, 0), (7
, 963), (8, 189), (9, 0), (10, 0), (11, 0), (12, 0), (13, 724), (
14, 329), (15, 0), (16, 0), (17, 0), (18, 0), (19, 549), (20, 243
), (21, 0), (22, 0), (23, 0), (24, 0), (25, 144), (26, 424), (27
, 0), (28, 0), (29, 0), (30, 0), (31, 119), (32, 328), (33, 0), (
34, 0), (35, 0), (36, 0), (37, 126), (38, 339), (39, 0), (40, 0)
, (41, 0), (42, 0), (43, 126), (44, 357), (45, 0), (46, 0), (47,
0), (48, 0), (49, 107), (50, 225), (51, 0), (52, 0), (53, 0), (54
, 0), (55, 79), (56, 609), (57, 0), (58, 0), (59, 0), (60, 0), (
61, 181), (62, 356), (63, 0), (64, 0), (65, 0), (66, 0), (67, 70
), (68, 298), (69, 0), (70, 0), (71, 0), (72, 0), (73, 23), (74,
164), (75, 0), (76, 0), (77, 0), (78, 0), (79, 26), (80, 354), (
81, 0), (82, 0), (83, 0), (84, 0), (85, 47), (86, 341), (87, 0),
(88, 0), (89, 0), (90, 0), (91, 139), (92, 257), (93, 0), (94, 0
), (95, 0), (96, 0), (97, 104), (98, 505), (99, 0), (100, 0), (1
01, 0), (102, 0), (103, 192), (104, 224), (105, 0), (106, 0), (1
07, 0), (108, 0), (109, 114), (110, 310), (111, 0), (112, 0), (1
13, 0), (114, 0), (115, 32), (116, 183), (117, 0), (118, 0), (119
, 0), (120, 0), (121, 238), (122, 198), (123, 0), (124, 0), (125
, 0), (126, 0), (127, 117), (128, 327), (129, 0), (130, 0), (131
, 0), (132, 0), (133, 110), (134, 342), (135, 0), (136, 0), (137
, 0), (138, 0), (139, 118), (140, 342), (141, 0), (142, 0), (143
, 0), (144, 0), (145, 145), (146, 323), (147, 0), (148, 0), (149
, 0), (150, 0), (151, 152), (152, 324), (153, 0), (154, 0), (155
, 0), (156, 0), (157, 161), (158, 323), (159, 0), (160, 0), (161
, 0), (162, 0), (163, 175), (164, 317), (165, 0), (166, 0), (167
139
Level 33
, 0), (168, 0), (169, 183), (170, 317), (171, 0), (172, 0), (173
, 0), (174, 0), (175, 171), (176, 337), (177, 0), (178, 0), (179
, 0), (180, 0), (181, 198), (182, 318), (183, 0), (184, 0), (185
, 0), (186, 0), (187, 241), (188, 283), (189, 0), (190, 0), (191
, 0), (192, 0), (193, 1348), (194, 272), (195, 0), (196, 0), (197
, 0), (198, 0), (199, 0), (200, 0), (201, 0), (202, 0), (203, 0)
, (204, 0), (205, 0), (206, 0), (207, 0), (208, 0), (209, 0), (2
10, 0), (211, 0), (212, 0), (213, 0), (214, 0), (215, 0), (216, 0
), (217, 0), (218, 0), (219, 0), (220, 0), (221, 0), (222, 0), (
223, 0), (224, 0), (225, 0), (226, 0), (227, 0), (228, 0), (229,
0), (230, 0), (231, 0), (232, 0), (233, 0), (234, 0), (235, 0), (
236, 0), (237, 0), (238, 0), (239, 0), (240, 0), (241, 0), (242,
0), (243, 0), (244, 0), (245, 0), (246, 0), (247, 0), (248, 0), (
249, 0), (250, 0), (251, 0), (252, 0), (253, 0), (254, 0), (255,
0)]
>>> sum([x for x in [Link]() if x != 0][:-2])
17424
140
Level 33
gremlins
Final Link
[Link]
141
Appendix: Links
Links
Documentation
The Python Standard Library: ([Link]
PEP 8: Style Guide for Python Code([Link]
PIL: Python Imaging Library(fork that works with Python 3.x)
([Link]
Problems
Level 0:
problem: [Link]
unlock official solution:
[Link]
Level 1:
problem: [Link]
unlock official solution: [Link]
Level 2:
problem: [Link]
unlock official solution:
[Link]
Level 3:
problem: [Link]
unlock official solution:
[Link]
Level 4:
problem: [Link]
unlock official solution:
[Link]
Level 5:
problem: [Link]
142
Appendix: Links
unlock official solution:
[Link]
Level 6:
problem: [Link]
unlock official solution:
[Link]
Level 7:
problem: [Link]
unlock official solution:
[Link]
Level 8:
problem: [Link]
unlock official solution:
[Link]
Level 9:
problem: [Link]
unlock official solution:
[Link]
username: huge
password: file
Level 10:
problem: [Link]
unlock official solution:
[Link]
username: huge
password: file
Level 11:
problem: [Link]
unlock official solution:
[Link]
username: huge
password: file
Level 12:
problem: [Link]
unlock official solution:
[Link]
143
Appendix: Links
username: huge
password: file
Level 13:
problem: [Link]
unlock official solution:
[Link]
username: huge
password: file
Level 14:
problem: [Link]
unlock official solution:
[Link]
username: huge
password: file
Level 15:
problem: [Link]
unlock official solution:
[Link]
username: huge
password: file
Level 16:
problem: [Link]
unlock official solution:
[Link]
username: huge
password: file
Level 17:
problem: [Link]
unlock official solution:
[Link]
username: huge
password: file
Level 18:
problem: [Link]
unlock official solution:
[Link]
144
Appendix: Links
username: huge
password: file
Level 19:
problem: [Link]
unlock official solution:
[Link]
username: butter
password: fly
Level 20:
problem: [Link]
username: butter
password: fly
Level 21: NO LINK(inside the zip file from Level 20)
unlock official solution:
[Link]
Level 22:
problem: [Link]
unlock official solution:
[Link]
username: butter
password: fly
Level 23:
problem: [Link]
unlock official solution:
[Link]
username: butter
password: fly
Level 24:
problem: [Link]
unlock official solution:
[Link]
username: butter
password: fly
Level 25:
problem: [Link]
unlock official solution:
145
Appendix: Links
[Link]
username: butter
password: fly
Level 26:
problem: [Link]
unlock official solution:
[Link]
username: butter
password: fly
Level 27:
problem: [Link]
unlock official solution: [Link]
username: butter
password: fly
Level 28:
problem: [Link]
unlock official solution:
[Link]
username: repeat
password: switch
Level 29: -problem: [Link]
unlock official solution:
[Link]
username: repeat
password: switch
Level 30:
problem: [Link]
unlock official solution:
[Link]
username: repeat
password: switch
Level 31:
problem: [Link]
unlock official solution:
[Link]
username: repeat
146
Appendix: Links
password: switch
username(after clicking the image): kohsamui
password(after clicking the image): thailand
Level 32:
problem: [Link]
unlock official solution:
[Link]
username: kohsamui
password: thailand
Level 33:
problem: [Link]
unlock official solution:
[Link]
username: kohsamui
password: thailand
147