···11+import fileinput
22+from utils import Point
33+44+55+def knot_hash(msg):
66+ lengths = [ord(x) for x in msg] + [17, 31, 73, 47, 23]
77+ sparse = range(0, 256)
88+ pos = 0
99+ skip = 0
1010+1111+ for _ in range(64):
1212+ for l in lengths:
1313+ for i in range(l // 2):
1414+ x = (pos + i) % len(sparse)
1515+ y = (pos + l - i - 1) % len(sparse)
1616+ sparse[x], sparse[y] = sparse[y], sparse[x]
1717+1818+ pos = pos + l + skip % len(sparse)
1919+ skip += 1
2020+2121+ sparse = sparse
2222+ dense = []
2323+2424+ for i in range(16):
2525+ res = 0
2626+ for j in range(0, 16):
2727+ res ^= sparse[(i * 16) + j]
2828+2929+ dense.append(res)
3030+3131+ return ''.join('%02x' % x for x in dense)
3232+3333+3434+KEY_STRING = fileinput.input()[0].strip()
3535+DISK = set()
3636+3737+for x in range(128):
3838+ hash_hex = knot_hash(KEY_STRING + '-' + str(x))
3939+ hash_bits = ''.join('{0:04b}'.format(int(x, 16)) for x in hash_hex)
4040+ for y, b in enumerate(hash_bits):
4141+ if b == '1':
4242+ DISK.add(Point(x, y))
4343+4444+regions = 0
4545+seen = set()
4646+4747+for p in DISK:
4848+ if p in seen:
4949+ continue
5050+5151+ queue = [p]
5252+ while queue:
5353+ np = queue.pop()
5454+ seen.add(np)
5555+ for n in np.neighbours_4():
5656+ if n in DISK and n not in seen:
5757+ queue.append(n)
5858+5959+ regions += 1
6060+6161+print "Number of used squares:", len(DISK)
6262+print "Number of regions:", regions