├── palindromic-palindrome.py ├── README.md ├── restricted-sum.py ├── binary-count.py ├── hamming-distance2.py ├── elementary ├── secret-message.py ├── days-between.py ├── index-power.py ├── count-inversions.py ├── right-to-left.py ├── monkey-typing.py ├── boolean-algebra.py ├── friends.py └── building-base.py ├── mine ├── flatten-a-list.py ├── coin-golf.py ├── achilles-and-the-tortoise.py ├── call-to-home.py ├── broken-clock.py └── hexagon-spiral.py ├── restricted-prime.py ├── digits-multiplication.py ├── pycon tw 2014 ├── simple-hashlib.py └── behind-2048.py ├── home ├── prime-palindrome-golf.py ├── pawn-brotherhood.py ├── golden-pyramid.py ├── moore_neighbourhood.py ├── how-to-find-friends.py └── the-flat-dictionary.py ├── number-radix.py ├── even-last.py ├── spaceship-purchase.py ├── common-words.py ├── median.py ├── multiplication-table.py ├── feed-pigeons.py ├── most-wanted-letter.py ├── ice base ├── the-greatest-common-divisor.py ├── oil-pie.py └── simple-areas.py ├── electronic station ├── test.py ├── letter-queue.py ├── clock-angle.py ├── weak-point.py ├── moria-doors.py └── parse-array.py ├── incinerator ├── rotate-hole.py ├── bird-language.py ├── probably-dice.py └── word-pattern.py ├── three-words.py ├── absolute-sorting.py ├── most-numbers.py ├── scientific expedition ├── verify-anagrams.py ├── digit-stack.py ├── fibonacci-golf.py ├── square-spiral.py ├── network-attack.py ├── life-counter.py └── playfair-cipher.py ├── all-in-row.py ├── end-of-other.py ├── skew-symmetric-matrix.py ├── stick-sawing.py ├── fizz-buzz.py ├── ghosts-age.py ├── counting-tiles.py ├── matrix-transpose.py ├── weekend-counter.py ├── humpty-dumpty.py ├── stair-steps.py ├── striped-words.py ├── triangle-angles.py ├── loading-cargo.py ├── determinant.py ├── destination-in-spiral.py ├── friendly-number.py ├── find-ip.py ├── brackets.py ├── painting-wall.py ├── area-of-a-convex-polygon.py ├── box-probability.py ├── digits-doublets.py ├── number-guess.py ├── shortest-knight-path.py ├── ore-in-the-desert.py ├── cakes-rows.py ├── hidden-word.py ├── numbered-triangles.py ├── speechmodule.py ├── auto-painting.py ├── mathematically-lucky-tickets.py ├── determine-the-order.py ├── calculate-islands.py ├── mono-captcha.py ├── the-square-chest.py ├── three-points-circle.py ├── convex-hull.py ├── colder-warmer.py ├── url-normalization.py ├── disposable-teleports.py ├── radiation-search.py ├── cipher-crossword.py ├── digging-a-canal.py ├── how-much-gold.py ├── water-jars.py ├── hubspot-amulet.py ├── bit-message.py ├── web-log-sessions.py ├── anagrams-by-stacks.py ├── simplification.py ├── matrix-pattern.py ├── 8-puzzle.py ├── minesweeper.py ├── bats-bunker.py ├── express-delivery.py ├── magic-square.py ├── haunted-house.py └── open-labyrinth.py /palindromic-palindrome.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | "a\";]1-::[x==x:x adbmal=oikcehc;";checkio=lambda x:x==x[::-1];"\a" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | checkio 2 | ======= 3 | 4 | solutions of checkio 5 | 6 | You are welcome to follow my 7 | Checkio ID: hujingyuan 8 | 9 | -------------------------------------------------------------------------------- /restricted-sum.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(data): 5 | if len(data) == 0: 6 | return 0 7 | return data[0] + checkio(data[1:]) 8 | 9 | 10 | if __name__ == "__main__": 11 | assert checkio([1,2,3]) == 6, "first test" -------------------------------------------------------------------------------- /binary-count.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | def checkio(number): 3 | return bin(number).count('1') 4 | 5 | #These "asserts" using only for self-checking and not necessary for auto-testing 6 | if __name__ == '__main__': 7 | assert checkio(4) == 1 8 | assert checkio(15) == 4 9 | assert checkio(1) == 1 10 | assert checkio(1022) == 9 11 | -------------------------------------------------------------------------------- /hamming-distance2.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(n, m): 5 | return str(bin(n ^ m)).count('1') 6 | 7 | 8 | if __name__ == '__main__': 9 | #These "asserts" using only for self-checking and not necessary for auto-testing 10 | assert checkio(117, 17) == 3, "First example" 11 | assert checkio(1, 2) == 2, "Second example" 12 | assert checkio(16, 15) == 5, "Third example" -------------------------------------------------------------------------------- /elementary/secret-message.py: -------------------------------------------------------------------------------- 1 | def find_message(text): 2 | return "".join([c for c in text if c.isupper()]) 3 | 4 | if __name__ == '__main__': 5 | #These "asserts" using only for self-checking and not necessary for auto-testing 6 | assert find_message(u"How are you? Eh, ok. Low or Lower? Ohhh.") == "HELLO", "hello" 7 | assert find_message(u"hello world!") == "", "Nothing" 8 | assert find_message(u"HELLO WORLD!!!") == "HELLOWORLD", "Capitals" 9 | -------------------------------------------------------------------------------- /elementary/days-between.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | def days_diff(date1, date2): 4 | return abs((datetime.date(*date1)-datetime.date(*date2)).days) 5 | 6 | if __name__ == '__main__': 7 | #These "asserts" using only for self-checking and not necessary for auto-testing 8 | assert days_diff((1982, 4, 19), (1982, 4, 22)) == 3 9 | assert days_diff((2014, 1, 1), (2014, 8, 27)) == 238 10 | assert days_diff((2014, 8, 27), (2014, 1, 1)) == 238 11 | -------------------------------------------------------------------------------- /mine/flatten-a-list.py: -------------------------------------------------------------------------------- 1 | def r(a,b): 2 | if type(b)==int: 3 | a.append(b) 4 | return a 5 | return reduce(r,b,a) 6 | 7 | def flat_list(a): 8 | return reduce(r,a,[]) 9 | 10 | 11 | print flat_list([1, 2, 3]) == [1, 2, 3] 12 | print flat_list([1, [2, 2, 2], 4]) == [1, 2, 2, 2, 4] 13 | print flat_list([[[2]], [4, [5, 6, [6], 6, 6, 6], 7]]) == [2, 4, 5, 6, 6, 6, 6, 6, 7] 14 | print flat_list([-1, [1, [-2], 1], -1]) == [-1, 1, -2, 1, -1] -------------------------------------------------------------------------------- /restricted-prime.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(number): 5 | one = int(True) 6 | two = one + one 7 | chushu = two 8 | while chushu < number: 9 | total = int(False) 10 | while total <= number: 11 | total += chushu 12 | if total == number: 13 | return False 14 | chushu += one 15 | return True 16 | 17 | 18 | assert checkio(2) 19 | assert checkio(3) 20 | -------------------------------------------------------------------------------- /digits-multiplication.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(number): 5 | ret = 1 6 | for c in str(number): 7 | if int(c) != 0: 8 | ret *= int(c) 9 | 10 | return ret 11 | 12 | #These "asserts" using only for self-checking and not necessary for auto-testing 13 | if __name__ == '__main__': 14 | assert checkio(123405) == 120 15 | assert checkio(999) == 729 16 | assert checkio(1000) == 1 17 | assert checkio(1111) == 1 18 | -------------------------------------------------------------------------------- /mine/coin-golf.py: -------------------------------------------------------------------------------- 1 | def golf(c): 2 | l=len(c)+1 3 | c.sort() 4 | d=[[1]*l] 5 | i=0 6 | while 1: 7 | i+=1 8 | d.append([0]*l) 9 | for j in range(1,l): 10 | d[i][j]=d[i][j-1] 11 | if c[j-1]<=i: 12 | d[i][j]|=d[i-c[j-1]][j-1] 13 | if not sum(d[i]): 14 | return i 15 | return 0 16 | 17 | 18 | print golf([9, 2, 2, 1]) == 6 19 | print golf([1, 1, 1, 1]) == 5 20 | print golf([1, 2, 3, 4, 5]) == 16 -------------------------------------------------------------------------------- /elementary/index-power.py: -------------------------------------------------------------------------------- 1 | def index_power(array, n): 2 | if n >=len(array): 3 | return -1 4 | return array[n]**n 5 | 6 | if __name__ == '__main__': 7 | #These "asserts" using only for self-checking and not necessary for auto-testing 8 | assert index_power([1, 2, 3, 4], 2) == 9, "Square" 9 | assert index_power([1, 3, 10, 100], 3) == 1000000, "Cube" 10 | assert index_power([0, 1], 0) == 1, "Zero power" 11 | assert index_power([1, 2], 3) == -1, "IndexError" 12 | -------------------------------------------------------------------------------- /pycon tw 2014/simple-hashlib.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | 3 | def checkio(hashed_string, algorithm): 4 | m = hashlib.new(algorithm) 5 | m.update(hashed_string.encode('utf8')) 6 | return m.hexdigest() 7 | 8 | if __name__ == '__main__': 9 | #These "asserts" using only for self-checking and not necessary for auto-testing 10 | assert checkio(u'welcome', 'md5') == '40be4e59b9a2a2b5dffb918c0e86b3d7' 11 | assert checkio(u'happy spam', 'sha224') == '6e9dc3e01d57f1598c2b40ce59fc3527e698c77b15d0840ae96a8b5e' 12 | -------------------------------------------------------------------------------- /home/prime-palindrome-golf.py: -------------------------------------------------------------------------------- 1 | def isPrime(number): 2 | if number == 2: 3 | return True 4 | if number%2 == 0: 5 | return False 6 | for i in range(3, number/2, 2): 7 | if number%i == 0: 8 | return False 9 | return True 10 | 11 | def isPalindrome(number): 12 | return str(number) == str(number)[::-1] 13 | 14 | def golf(number): 15 | i = number 16 | while 1: 17 | i+=1 18 | if isPalindrome(i) and isPrime(i): 19 | return i 20 | return number + 1 21 | -------------------------------------------------------------------------------- /number-radix.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | def checkio(str_number, radix): 3 | try: 4 | return int(str_number, radix) 5 | except ValueError: 6 | return -1 7 | 8 | #These "asserts" using only for self-checking and not necessary for auto-testing 9 | if __name__ == '__main__': 10 | assert checkio(u"AF", 16) == 175, "Hex" 11 | assert checkio(u"101", 2) == 5, "Bin" 12 | assert checkio(u"101", 5) == 26, "5 base" 13 | assert checkio(u"Z", 36) == 35, "Z base" 14 | assert checkio(u"AB", 10) == -1, "B > A > 10" 15 | -------------------------------------------------------------------------------- /elementary/count-inversions.py: -------------------------------------------------------------------------------- 1 | def count_inversion(sequence): 2 | return sum(1 for i in range(len(sequence)) for j in range(i+1, len(sequence)) if sequence[i] > sequence[j]) 3 | 4 | if __name__ == '__main__': 5 | #These "asserts" using only for self-checking and not necessary for auto-testing 6 | assert count_inversion((1, 2, 5, 3, 4, 7, 6)) == 3, "Example" 7 | assert count_inversion((0, 1, 2, 3)) == 0, "Sorted" 8 | assert count_inversion((99, -99)) == 1, "Two numbers" 9 | assert count_inversion((5, 3, 2, 1, 0)) == 10, "Reversed" 10 | -------------------------------------------------------------------------------- /even-last.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | def checkio(array): 3 | """ 4 | sums even-indexes elements and multiply at the last 5 | """ 6 | if len(array) == 0: 7 | return 0 8 | return sum(array[::2])*array[-1] 9 | 10 | #These "asserts" using only for self-checking and not necessary for auto-testing 11 | if __name__ == '__main__': 12 | assert checkio([0, 1, 2, 3, 4, 5]) == 30, "(0+2+4)*5=30" 13 | assert checkio([1, 3, 5]) == 30, "(1+5)*5=30" 14 | assert checkio([6]) == 36, "(6)*6=36" 15 | assert checkio([]) == 0, "Empty" 16 | -------------------------------------------------------------------------------- /spaceship-purchase.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | def checkio(data): 4 | 5 | a, b, c, d = data 6 | if a >= c: 7 | return c 8 | while a < c: 9 | a+=b 10 | if a >= c: 11 | return c 12 | c-=d 13 | if c <= a: 14 | return a 15 | 16 | 17 | 18 | #These "asserts" using only for self-checking and not necessary for auto-testing 19 | if __name__ == '__main__': 20 | assert checkio([150, 50, 1000, 100]) == 450, "1st example" 21 | assert checkio([150, 50, 900, 100]) == 400, "2nd example" 22 | -------------------------------------------------------------------------------- /common-words.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | def checkio(first, second): 3 | s1 = set(first.split(',')) 4 | s2 = set(second.split(',')) 5 | return ','.join(sorted(s1.intersection(s2))) 6 | 7 | #These "asserts" using only for self-checking and not necessary for auto-testing 8 | if __name__ == '__main__': 9 | assert checkio(u"hello,world", u"hello,earth") == "hello", "Hello" 10 | assert checkio(u"one,two,three", u"four,five,six") == "", "Too different" 11 | assert checkio(u"one,two,three", u"four,five,one,two,six,three") == "one,three,two", "1 2 3" 12 | -------------------------------------------------------------------------------- /median.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | def checkio(data): 4 | sd = sorted(data) 5 | N = len(data) - 1 6 | a = sd[N // 2] 7 | b = sd[(N + 1) // 2] 8 | return (a+b) / 2.0 9 | 10 | #These "asserts" using only for self-checking and not necessary for auto-testing 11 | if __name__ == '__main__': 12 | assert checkio([1, 2, 3, 4, 5]) == 3, "Sorted list" 13 | assert checkio([3, 1, 2, 5, 3]) == 3, "Not sorted list" 14 | assert checkio([1, 300, 2, 200, 1]) == 2, "It's not an average" 15 | assert checkio([3, 6, 20, 99, 10, 15]) == 12.5, "Even length" -------------------------------------------------------------------------------- /multiplication-table.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import operator 3 | 4 | 5 | def checkio(first, second): 6 | ops = [operator.or_, operator.and_, operator.xor] 7 | ret = 0 8 | for i in bin(first)[2:]: 9 | for op in ops: 10 | ret += int(''.join([str(op(int(i), int(x))) for x in bin(second)[2:]]), 2) 11 | return ret 12 | 13 | #These "asserts" using only for self-checking and not necessary for auto-testing 14 | if __name__ == '__main__': 15 | assert checkio(4, 6) == 38 16 | assert checkio(2, 7) == 28 17 | assert checkio(7, 2) == 18 -------------------------------------------------------------------------------- /elementary/right-to-left.py: -------------------------------------------------------------------------------- 1 | def left_join(phrases): 2 | return ",".join(phrases).replace('right', 'left') 3 | 4 | if __name__ == '__main__': 5 | #These "asserts" using only for self-checking and not necessary for auto-testing 6 | assert left_join(("left", "right", "left", "stop")) == "left,left,left,stop", "All to left" 7 | assert left_join(("bright aright", "ok")) == "bleft aleft,ok", "Bright Left" 8 | assert left_join(("brightness wright",)) == "bleftness wleft", "One phrase" 9 | assert left_join(("enough", "jokes")) == "enough,jokes", "Nothing to replace" 10 | -------------------------------------------------------------------------------- /feed-pigeons.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(n): 5 | total = 0 6 | for i in range(1, 10): 7 | pigeons = sum(range(1, i + 1)) 8 | total += pigeons 9 | if total >= n: 10 | return max(sum(range(1, i)), pigeons - total + n) 11 | return 0 12 | 13 | #These "asserts" using only for self-checking and not necessary for auto-testing 14 | if __name__ == '__main__': 15 | assert checkio(1) == 1, "1st example" 16 | assert checkio(2) == 1, "2nd example" 17 | assert checkio(5) == 3, "3rd example" 18 | assert checkio(10) == 6, "4th example" -------------------------------------------------------------------------------- /mine/achilles-and-the-tortoise.py: -------------------------------------------------------------------------------- 1 | def chase(a1_speed, t2_speed, advantage): 2 | return advantage + float(t2_speed*advantage)/(a1_speed-t2_speed) 3 | 4 | if __name__ == '__main__': 5 | #These "asserts" using only for self-checking and not necessary for auto-testing 6 | def almost_equal(checked, correct, significant_digits): 7 | precision = 0.1 ** significant_digits 8 | return correct - precision < checked < correct + precision 9 | 10 | assert almost_equal(chase(6, 3, 2), 4, 8), "example" 11 | assert almost_equal(chase(10, 1, 10), 11.111111111, 8), "long number" 12 | 13 | -------------------------------------------------------------------------------- /most-wanted-letter.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | import re 4 | from collections import Counter 5 | 6 | def checkio(text): 7 | print re.findall("\w", text.lower()) 8 | text = "".join(re.findall("\w", text.lower())) 9 | print text 10 | return Counter(text).most_common()[0][0] 11 | 12 | 13 | #These "asserts" using only for self-checking and not necessary for auto-testing 14 | if __name__ == '__main__': 15 | assert checkio(u"Hello World!") == "l", "Hello test" 16 | assert checkio(u"How do you do?") == "o", "O is most wanted" 17 | assert checkio(u"One") == "e", "All letter only once." 18 | 19 | -------------------------------------------------------------------------------- /elementary/monkey-typing.py: -------------------------------------------------------------------------------- 1 | def count_words(text, words): 2 | return sum(1 for word in words if text.lower().find(word) >= 0) 3 | 4 | 5 | if __name__ == '__main__': 6 | #These uu"1sserts" using only for self-checking and not necessary for auto-testing 7 | assert count_words(u"How aresjfhdskfhskd you?", {u"how", u"are", u"you", u"hello"}) == 3, "Example" 8 | assert count_words(u"Bananas, give me bananas!!!", {u"banana", u"bananas"}) == 2, "BANANAS!" 9 | assert count_words(u"Lorem ipsum dolor sit amet, consectetuer adipiscing elit.", 10 | {u"sum", u"hamlet", u"infinity", u"anything"}) == 1, "Weird text" 11 | -------------------------------------------------------------------------------- /ice base/the-greatest-common-divisor.py: -------------------------------------------------------------------------------- 1 | def gcd(a, b): 2 | if b > a: 3 | a, b = b, a 4 | if b == 0: 5 | return a 6 | return gcd(b, a%b) 7 | 8 | def greatest_common_divisor(*args): 9 | return reduce(gcd, args) 10 | 11 | if __name__ == '__main__': 12 | #These "asserts" using only for self-checking and not necessary for auto-testing 13 | assert greatest_common_divisor(6, 4) == 2, "Simple" 14 | assert greatest_common_divisor(2, 4, 8) == 2, "Three arguments" 15 | assert greatest_common_divisor(2, 3, 5, 7, 11) == 1, "Prime numbers" 16 | assert greatest_common_divisor(3, 9, 3, 9) == 3, "Repeating arguments" 17 | -------------------------------------------------------------------------------- /electronic station/test.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import os 3 | import os.path 4 | 5 | def visit(arg, dirname, names): 6 | print dirname, arg 7 | for name in names: 8 | print name 9 | subname = os.path.join(dirname, name) 10 | if os.path.isdir(subname): 11 | print ' %s/' % name 12 | else: 13 | print ' %s' % name 14 | print 15 | 16 | os.mkdir('example') 17 | os.mkdir('example/one') 18 | f = open('example/one/file.txt', 'wt') 19 | f.write('contents') 20 | f.close() 21 | f = open('example/two.txt', 'wt') 22 | f.write('contents') 23 | f.close() 24 | os.path.walk('example', visit, '(User data)') -------------------------------------------------------------------------------- /incinerator/rotate-hole.py: -------------------------------------------------------------------------------- 1 | def rotate(state, pipe_numbers): 2 | return [i for i in range(len(state)) if all([state[(j-i)%len(state)] for j in pipe_numbers])] 3 | 4 | 5 | if __name__ == '__main__': 6 | #These "asserts" using only for self-checking and not necessary for auto-testing 7 | assert rotate([1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1], [0, 1]) == [1, 8], "Example" 8 | assert rotate([1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1], [0, 1, 2]) == [], "Mission impossible" 9 | assert rotate([1, 0, 0, 0, 1, 1, 0, 1], [0, 4, 5]) == [0], "Don't touch it" 10 | assert rotate([1, 0, 0, 0, 1, 1, 0, 1], [5, 4, 5]) == [0, 5], "Two cannonballs in the same pipe" 11 | -------------------------------------------------------------------------------- /home/pawn-brotherhood.py: -------------------------------------------------------------------------------- 1 | def guide(pawns): 2 | row, col = pawns[0], pawns[1] 3 | g1 = chr(ord(row)-1)+chr(ord(col)-1) 4 | g2 = chr(ord(row)+1)+chr(ord(col)-1) 5 | return [g1, g2] 6 | 7 | def safe_pawns(pawns): 8 | c = 0 9 | for i in pawns: 10 | for g in guide(i): 11 | if g in pawns: 12 | c+=1 13 | break 14 | return c 15 | 16 | 17 | if __name__ == '__main__': 18 | #These "asserts" using only for self-checking and not necessary for auto-testing 19 | assert safe_pawns({"b4", "d4", "f4", "c3", "e3", "g5", "d2"}) == 6 20 | assert safe_pawns({"b4", "c4", "d4", "e4", "f4", "g4", "e5"}) == 1 21 | -------------------------------------------------------------------------------- /incinerator/bird-language.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | def translate(phrase): 4 | pattern = re.compile('(([aeiouy])[aeiouy]{2})|(([^aeiouy])[aeiouy])') 5 | return ' '.join([''.join([i.group(2) or i.group(4) for i in pattern.finditer(word)]) for word in phrase.split(' ')]) 6 | 7 | if __name__ == '__main__': 8 | #These "asserts" using only for self-checking and not necessary for auto-testing 9 | assert translate(u"hieeelalaooo") == "hello", "Hi!" 10 | assert translate(u"hoooowe yyyooouuu duoooiiine") == "how you doin", "Joey?" 11 | assert translate(u"aaa bo cy da eee fe") == "a b c d e f", "Alphabet" 12 | assert translate(u"sooooso aaaaaaaaa") == "sos aaa", "Mayday, mayday" 13 | -------------------------------------------------------------------------------- /three-words.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | def checkio(words): 3 | count = 0 4 | for word in words.split(' '): 5 | if word[0].isdigit(): 6 | count = 0 7 | else: 8 | count += 1 9 | if count == 3: 10 | return True 11 | return False 12 | 13 | #These "asserts" using only for self-checking and not necessary for auto-testing 14 | if __name__ == '__main__': 15 | assert checkio(u"Hello World hello") == True, "Hello" 16 | assert checkio(u"He is 123 man") == False, "123 man" 17 | assert checkio(u"1 2 3 4") == False, "Digits" 18 | assert checkio(u"bla bla bla bla") == True, "Bla Bla" 19 | assert checkio(u"Hi") == False, "Hi" 20 | -------------------------------------------------------------------------------- /electronic station/letter-queue.py: -------------------------------------------------------------------------------- 1 | def letter_queue(commands): 2 | l = [] 3 | for c in commands: 4 | if c.startswith('PUSH'): 5 | l.append(c[5]) 6 | else: 7 | if len(l) > 0: 8 | l.pop(0) 9 | return ''.join(l) 10 | 11 | if __name__ == '__main__': 12 | #These "asserts" using only for self-checking and not necessary for auto-testing 13 | assert letter_queue(["PUSH A", "POP", "POP", "PUSH Z", "PUSH D", "PUSH O", "POP", "PUSH T"]) == "DOT", "dot example" 14 | assert letter_queue(["POP", "POP"]) == "", "Pop, Pop, empty" 15 | assert letter_queue(["PUSH H", "PUSH I"]) == "HI", "Hi!" 16 | assert letter_queue([]) == "", "Nothing" 17 | -------------------------------------------------------------------------------- /absolute-sorting.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | def checkio(numbers_array): 4 | return sorted(numbers_array, key=abs) 5 | 6 | #These "asserts" using only for self-checking and not necessary for auto-testing 7 | if __name__ == '__main__': 8 | def check_it(array): 9 | if not isinstance(array, (list, tuple)): 10 | raise TypeError("The result should be a list or tuple.") 11 | return list(array) 12 | 13 | assert check_it(checkio((-20, -5, 10, 15))) == [-5, 10, 15, -20], "Example" # or (-5, 10, 15, -20) 14 | assert check_it(checkio((1, 2, 3, 0))) == [0, 1, 2, 3], "Positive numbers" 15 | assert check_it(checkio((-1, -2, -3, 0))) == [0, -1, -2, -3], "Negative numbers" 16 | -------------------------------------------------------------------------------- /most-numbers.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | def checkio(*args): 3 | if len(args) == 0: 4 | return 0 5 | return max(args) - min(args) 6 | 7 | #These "asserts" using only for self-checking and not necessary for auto-testing 8 | if __name__ == '__main__': 9 | def almost_equal(checked, correct, significant_digits): 10 | precision = 0.1 ** significant_digits 11 | return correct - precision < checked < correct + precision 12 | 13 | assert almost_equal(checkio(1, 2, 3), 2, 3), "3-1=2" 14 | assert almost_equal(checkio(5, -5), 10, 3), "5-(-5)=10" 15 | assert almost_equal(checkio(10.2, -2.2, 0, 1.1, 0.5), 12.4, 3), "10.2-(-2.2)=12.4" 16 | assert almost_equal(checkio(), 0, 3), "Empty" 17 | -------------------------------------------------------------------------------- /scientific expedition/verify-anagrams.py: -------------------------------------------------------------------------------- 1 | import string 2 | 3 | def normalize(s): 4 | return sorted([c for c in string.lower(s) if c.isalpha()]) 5 | 6 | def verify_anagrams(first_word, second_word): 7 | return normalize(first_word) == normalize(second_word) 8 | 9 | if __name__ == '__main__': 10 | #These "asserts" using only for self-checking and not necessary for auto-testing 11 | assert isinstance(verify_anagrams(u"a", u"z"), bool), "Boolean!" 12 | assert verify_anagrams(u"Programming", u"Gram Ring Mop") == True, "Gram of code" 13 | assert verify_anagrams(u"Hello", u"Ole Oh") == False, "Hello! Ole Oh!" 14 | assert verify_anagrams(u"Kyoto", u"Tokyo") == True, "The global warming crisis of 3002" 15 | 16 | -------------------------------------------------------------------------------- /all-in-row.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | def checkio(data): 4 | ret = [] 5 | #replace this for solution 6 | def traverse(data): 7 | for d in data: 8 | if isinstance(d, list): 9 | traverse(d) 10 | else: 11 | ret.append(d) 12 | 13 | traverse(data) 14 | return ret 15 | 16 | 17 | #These "asserts" using only for self-checking and not necessary for auto-testing 18 | if __name__ == '__main__': 19 | assert checkio([1, 2, 3]) == [1, 2, 3], 'First example' 20 | assert checkio([1, [2, 2, 2], 4]) == [1, 2, 2, 2, 4], 'Second example' 21 | assert checkio([[[2]], [4, [5, 6, [6], 6, 6, 6], 7]]) ==\ 22 | [2, 4, 5, 6, 6, 6, 6, 6, 7], 'Third example' 23 | -------------------------------------------------------------------------------- /end-of-other.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import itertools 3 | 4 | 5 | def checkio(words_set): 6 | for pair in itertools.product(words_set, repeat=2): 7 | if len(pair[0]) < len(pair[1]) and pair[1].endswith(pair[0]): 8 | return True 9 | return False 10 | 11 | #These "asserts" using only for self-checking and not necessary for auto-testing 12 | if __name__ == '__main__': 13 | assert checkio({u"hello", u"lo", u"he"}) == True, "helLO" 14 | assert checkio({u"hello", u"la", u"hellow", u"cow"}) == False, "hellow la cow" 15 | assert checkio({u"walk", u"duckwalk"}) == True, "duck to walk" 16 | assert checkio({u"one"}) == False, "Only One" 17 | assert checkio({u"helicopter", u"li", u"he"}) == False, "Only end" -------------------------------------------------------------------------------- /skew-symmetric-matrix.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | def checkio(matrix): 4 | length = len(matrix) 5 | for col in range(length): 6 | for row in range(col+1): 7 | if matrix[col][row] != -matrix[row][col]: 8 | return False 9 | return True 10 | 11 | 12 | #These "asserts" using only for self-checking and not necessary for auto-testing 13 | if __name__ == '__main__': 14 | assert checkio([ 15 | [0, 1, 2], 16 | [-1, 0, 1], 17 | [-2, -1, 0]]) == True, "1st example" 18 | assert checkio([ 19 | [0, 1, 2], 20 | [-1, 1, 1], 21 | [-2, -1, 0]]) == False, "2nd example" 22 | assert checkio([ 23 | [0, 1, 2], 24 | [-1, 0, 1], 25 | [-3, -1, 0]]) == False, "3rd example" -------------------------------------------------------------------------------- /stick-sawing.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | def fn(n): 3 | return n*(n+1)*(n+2)/6 4 | 5 | def f(n): 6 | return n*(n+1)/2 7 | 8 | def checkio(number): 9 | for i in range(44, 0, -1): 10 | for j in range(1, 46-i): 11 | if fn(j+i-1)-fn(j-1) == number: 12 | l = [] 13 | for k in range(i): 14 | l.append(f(j+k)) 15 | return l 16 | return [] 17 | 18 | #These "asserts" using only for self-checking and not necessary for auto-testing 19 | if __name__ == '__main__': 20 | assert checkio(64) == [15, 21, 28], "1st example" 21 | assert checkio(371) == [36, 45, 55, 66, 78, 91], "1st example" 22 | assert checkio(225) == [105, 120], "1st example" 23 | assert checkio(882) == [], "1st example" 24 | -------------------------------------------------------------------------------- /fizz-buzz.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | #Your optional code here 3 | #You can import some modules or create additional functions 4 | 5 | 6 | def checkio(number): 7 | if number % 15 == 0: 8 | return 'Fizz Buzz' 9 | if number % 3 == 0: 10 | return 'Fizz' 11 | if number % 5 == 0: 12 | return 'Buzz' 13 | return str(number) 14 | 15 | #Some hints: 16 | #Convert a number in the string with str(n) 17 | 18 | #These "asserts" using only for self-checking and not necessary for auto-testing 19 | if __name__ == '__main__': 20 | assert checkio(15) == "Fizz Buzz", "15 is divisible by 3 and 5" 21 | assert checkio(6) == "Fizz", "6 is divisible by 3" 22 | assert checkio(5) == "Buzz", "5 is divisible by 5" 23 | assert checkio(7) == "7", "7 is not divisible by 3 or 5" -------------------------------------------------------------------------------- /ghosts-age.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(opacity): 5 | if opacity == 10000: 6 | return 0 7 | if opacity == 9999: 8 | return 1 9 | 10 | dx = 10002 - opacity 11 | now = 1 12 | nxt = 2 13 | for i in range(2, 20): 14 | now, nxt = nxt, now + nxt 15 | if nxt + i >= dx: 16 | return now + nxt + i - dx 17 | return 0 18 | 19 | #These "asserts" using only for self-checking and not necessary for auto-testing 20 | 21 | 22 | if __name__ == '__main__': 23 | assert checkio(10000) == 0, "Newborn" 24 | assert checkio(9999) == 1, "1 year" 25 | assert checkio(9997) == 2, "2 years" 26 | assert checkio(9994) == 3, "3 years" 27 | assert checkio(9995) == 4, "4 years" 28 | assert checkio(9990) == 5, "5 years" -------------------------------------------------------------------------------- /counting-tiles.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | from math import ceil 3 | 4 | def checkio(radius): 5 | """count tiles""" 6 | solid, partial = 0, 0 7 | top = radius 8 | bottom = radius 9 | for i in range(1, int(radius)+1): 10 | bottom = (radius**2-i**2)**.5 11 | solid += int(bottom) 12 | partial += int(ceil(top))-int(bottom) 13 | top = bottom 14 | if int(radius) != radius: 15 | partial += int(ceil(bottom)) 16 | return [4*solid, 4*partial] 17 | 18 | #These "asserts" using only for self-checking and not necessary for auto-testing 19 | if __name__ == '__main__': 20 | assert checkio(2) == [4, 12], "N=2" 21 | assert checkio(3) == [16, 20], "N=3" 22 | assert checkio(2.1) == [4, 20], "N=2.1" 23 | assert checkio(2.5) == [12, 20], "N=2.5" 24 | -------------------------------------------------------------------------------- /matrix-transpose.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | def checkio(data): 3 | return [[x[i] for x in data] for i in range(len(data[0]))] 4 | 5 | #These "asserts" using only for self-checking and not necessary for auto-testing 6 | if __name__ == '__main__': 7 | assert checkio([[1, 2, 3], 8 | [4, 5, 6], 9 | [7, 8, 9]]) == [[1, 4, 7], 10 | [2, 5, 8], 11 | [3, 6, 9]], "Square matrix" 12 | assert checkio([[1, 4, 3], 13 | [8, 2, 6], 14 | [7, 8, 3], 15 | [4, 9, 6], 16 | [7, 8, 1]]) == [[1, 8, 7, 4, 7], 17 | [4, 2, 8, 9, 8], 18 | [3, 6, 3, 6, 1]], "Rectangle matrix" 19 | -------------------------------------------------------------------------------- /electronic station/clock-angle.py: -------------------------------------------------------------------------------- 1 | def clock_angle(time): 2 | hour, minute = time.split(':') 3 | hour = int(hour)%12 4 | minute = int(minute) 5 | hourAngle = 30.0*(hour+minute/60.0) 6 | minuteAngle = 6.0 * minute 7 | angle = (minuteAngle - hourAngle) % 360 8 | if angle > 180: 9 | angle = 360 - angle 10 | return angle 11 | 12 | if __name__ == '__main__': 13 | #These "asserts" using only for self-checking and not necessary for auto-testing 14 | assert clock_angle("02:30") == 105, "02:30" 15 | assert clock_angle("13:42") == 159, "13:42" 16 | assert clock_angle("01:42") == 159, "01:42" 17 | assert clock_angle("01:43") == 153.5, "01:43" 18 | assert clock_angle("00:00") == 0, "Zero" 19 | assert clock_angle("12:01") == 5.5, "Little later" 20 | assert clock_angle("18:00") == 180, "Opposite" 21 | -------------------------------------------------------------------------------- /weekend-counter.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | from datetime import date 3 | from datetime import timedelta 4 | 5 | 6 | def checkio(from_date, to_date): 7 | """ 8 | Count the days of rest 9 | """ 10 | count = 0 11 | day_count = (to_date - from_date).days + 1 12 | for single_date in [d for d in (from_date + timedelta(n) for n in range(day_count)) if d <= to_date]: 13 | if single_date.weekday() in [5, 6]: 14 | count += 1 15 | return count 16 | 17 | #These "asserts" using only for self-checking and not necessary for auto-testing 18 | if __name__ == '__main__': 19 | assert checkio(date(2013, 9, 18), date(2013, 9, 23)) == 2, "1st example" 20 | assert checkio(date(2013, 1, 1), date(2013, 2, 1)) == 8, "2nd example" 21 | assert checkio(date(2013, 2, 2), date(2013, 2, 3)) == 2, "3rd example" 22 | 23 | -------------------------------------------------------------------------------- /humpty-dumpty.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import math 3 | 4 | 5 | def checkio(height, width): 6 | a = width / 2.0 7 | c = height / 2.0 8 | if c < a: 9 | e = (1 - (c / a) ** 2) ** .5 10 | s = round(2 * math.pi * a ** 2 * (1 + (1 - e ** 2) / e * math.atanh(e)), 2) 11 | elif c == a: 12 | s = round(4 * math.pi * a ** 2, 2) 13 | else: 14 | e = (1 - (a / c) ** 2) ** .5 15 | s = round(2 * math.pi * a ** 2 * (1 + c / (a * e) * math.asin(e)), 2) 16 | v = round((4 * math.pi / 3) * a ** 2 * c, 2) 17 | return [v, s] 18 | 19 | #These "asserts" using only for self-checking and not necessary for auto-testing 20 | if __name__ == '__main__': 21 | assert checkio(4, 2) == [8.38, 21.48], "Prolate spheroid" 22 | assert checkio(2, 2) == [4.19, 12.57], "Sphere" 23 | assert checkio(2, 4) == [16.76, 34.69], "Oblate spheroid" 24 | -------------------------------------------------------------------------------- /stair-steps.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def dp(numbers, x, b): 5 | if x == -1: 6 | return 0 7 | if x == 0: 8 | if b: 9 | return numbers[0] 10 | return 0 11 | if b: 12 | return max(dp(numbers, x - 1, True), dp(numbers, x - 1, False)) + numbers[x] 13 | return dp(numbers, x - 1, True) 14 | 15 | 16 | def checkio(numbers): 17 | numbers.append(0) 18 | return dp(numbers, len(numbers) - 1, True) 19 | 20 | #These "asserts" using only for self-checking and not necessary for auto-testing 21 | if __name__ == '__main__': 22 | assert checkio([5, -3, -1, 2]) == 6, 'Fifth' 23 | assert checkio([5, 6, -10, -7, 4]) == 8, 'First' 24 | assert checkio([-11, 69, 77, -51, 23, 67, 35, 27, -25, 95]) == 393, 'Second' 25 | assert checkio([-21, -23, -69, -67, 1, 41, 97, 49, 27]) == 125, 'Third' 26 | print('All ok') -------------------------------------------------------------------------------- /striped-words.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import re 3 | 4 | VOWELS = "AEIOUY" 5 | CONSONANTS = "BCDFGHJKLMNPQRSTVWXZ" 6 | 7 | 8 | def checkio(text): 9 | count = 0 10 | words = re.split('\W+', text) 11 | pattern = '^[' + VOWELS + ']?([' + CONSONANTS + '][' + VOWELS + '])*[' + CONSONANTS + ']?$' 12 | for word in [word for word in words if len(word) != 0 and len(word) != 1]: 13 | if re.match(pattern, word, re.I): 14 | count += 1 15 | return count 16 | 17 | #These "asserts" using only for self-checking and not necessary for auto-testing 18 | if __name__ == '__main__': 19 | assert checkio(u"My name is ...") == 3, "All words are striped" 20 | assert checkio(u"Hello world") == 0, "No one" 21 | assert checkio(u"A quantity of striped words.") == 1, "Only of" 22 | assert checkio(u"Dog,cat,mouse,bird.Human.") == 3, "Dog, cat and human" 23 | -------------------------------------------------------------------------------- /elementary/boolean-algebra.py: -------------------------------------------------------------------------------- 1 | OPERATION_NAMES = ("conjunction", "disjunction", "implication", "exclusive", "equivalence") 2 | 3 | def boolean(x, y, operation): 4 | if operation == OPERATION_NAMES[0]: 5 | return int(x and y) 6 | if operation == OPERATION_NAMES[1]: 7 | return int(x or y) 8 | if operation == OPERATION_NAMES[2]: 9 | return int(not x or y) 10 | if operation == OPERATION_NAMES[3]: 11 | return int(not (x == y)) 12 | return int(x == y) 13 | 14 | if __name__ == '__main__': 15 | #These "asserts" using only for self-checking and not necessary for auto-testing 16 | assert boolean(1, 0, u"conjunction") == 0, "and" 17 | assert boolean(1, 0, u"disjunction") == 1, "or" 18 | assert boolean(1, 1, u"implication") == 1, "material" 19 | assert boolean(0, 1, u"exclusive") == 1, "xor" 20 | assert boolean(0, 1, u"equivalence") == 0, "same?" 21 | -------------------------------------------------------------------------------- /ice base/oil-pie.py: -------------------------------------------------------------------------------- 1 | import fractions 2 | 3 | 4 | def divide_pie(groups): 5 | n = sum([abs(x) for x in groups]) 6 | remain = fractions.Fraction(1, 1) 7 | for i in groups: 8 | if i > 0: 9 | remain -= fractions.Fraction(i, n) 10 | else: 11 | remain *= 1 - fractions.Fraction(abs(i), n) 12 | if remain < 0: 13 | remain = 0 14 | return remain.numerator, remain.denominator 15 | 16 | if __name__ == '__main__': 17 | #These "asserts" using only for self-checking and not necessary for auto-testing 18 | assert isinstance((2, -2), (tuple, list)), "Return tuple or list" 19 | assert tuple(divide_pie((2, -1, 3))) == (1, 18), "Example" 20 | assert tuple(divide_pie((1, 2, 3))) == (0, 1), "All know about the pie" 21 | assert tuple(divide_pie((-1, -1, -1))) == (8, 27), "One by one" 22 | assert tuple(divide_pie((10,))) == (0, 1), "All together" 23 | -------------------------------------------------------------------------------- /triangle-angles.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | from math import acos 3 | from math import pi 4 | 5 | 6 | def checkio(a, b, c): 7 | edges = [a, b, c] 8 | edges.sort() 9 | if edges[0] + edges[1] <= edges[2]: 10 | return [0, 0, 0] 11 | ang1 = round(acos((edges[1] ** 2 + edges[2] ** 2 - edges[0] ** 2) / float(2 * edges[1] * edges[2]))/pi*180) 12 | ang2 = round(acos((edges[0] ** 2 + edges[2] ** 2 - edges[1] ** 2) / float(2 * edges[0] * edges[2]))/pi*180) 13 | ang3 = 180 - ang1 - ang2 14 | 15 | #replace this for solution 16 | return [ang1, ang2, ang3] 17 | 18 | #These "asserts" using only for self-checking and not necessary for auto-testing 19 | if __name__ == '__main__': 20 | assert checkio(4, 4, 4) == [60, 60, 60], "All sides are equal" 21 | assert checkio(3, 4, 5) == [37, 53, 90], "Egyptian triangle" 22 | assert checkio(2, 2, 5) == [0, 0, 0], "It's can not be a triangle" 23 | -------------------------------------------------------------------------------- /ice base/simple-areas.py: -------------------------------------------------------------------------------- 1 | from math import pi 2 | 3 | 4 | def simple_areas(*args): 5 | if len(args) == 1: 6 | return args[0]**2*pi/4 7 | if len(args) == 2: 8 | return args[0]*args[1] 9 | p = sum(args)/2.0 10 | return (p*(p-args[0])*(p-args[1])*(p-args[2]))**0.5 11 | 12 | if __name__ == '__main__': 13 | #These "asserts" using only for self-checking and not necessary for auto-testing 14 | def almost_equal(checked, correct, significant_digits=2): 15 | precision = 0.1 ** significant_digits 16 | return correct - precision < checked < correct + precision 17 | 18 | assert almost_equal(simple_areas(3), 7.07), "Circle" 19 | assert almost_equal(simple_areas(2, 2), 4), "Square" 20 | assert almost_equal(simple_areas(2, 3), 6), "Rectangle" 21 | assert almost_equal(simple_areas(3, 5, 4), 6), "Triangle" 22 | assert almost_equal(simple_areas(1.5, 2.5, 2), 1.5), "Small triangle" 23 | -------------------------------------------------------------------------------- /incinerator/probably-dice.py: -------------------------------------------------------------------------------- 1 | def probability(dice_number, sides, target): 2 | return 0.0 3 | 4 | if __name__ == '__main__': 5 | #These are only used for self-checking and are not necessary for auto-testing 6 | def almost_equal(checked, correct, significant_digits=4): 7 | precision = 0.1 ** significant_digits 8 | return correct - precision < checked < correct + precision 9 | 10 | assert(almost_equal(probability(2, 6, 3), 0.0556)), "Basic example" 11 | assert(almost_equal(probability(2, 6, 4), 0.0833)), "More points" 12 | assert(almost_equal(probability(2, 6, 7), 0.1667)), "Maximum for two 6-sided dice" 13 | assert(almost_equal(probability(2, 3, 5), 0.2222)), "Small dice" 14 | assert(almost_equal(probability(2, 3, 7), 0.0000)), "Never!" 15 | assert(almost_equal(probability(3, 6, 7), 0.0694)), "Three dice" 16 | assert(almost_equal(probability(10, 10, 50), 0.0375)), "Many dice, many sides" 17 | -------------------------------------------------------------------------------- /incinerator/word-pattern.py: -------------------------------------------------------------------------------- 1 | import string 2 | def check_command(pattern, command): 3 | if len(str(bin(pattern)))-2 > len(command): 4 | return False 5 | a = ''.join([str(int(i.isalpha())) for i in command]) 6 | return pattern == string.atoi(a, 2) 7 | 8 | if __name__ == '__main__': 9 | #These "asserts" using only for self-checking and not necessary for auto-testing 10 | assert check_command(42, u"12a0b3e4") == True, "42 is the answer" 11 | assert check_command(101, u"ab23b4zz") == False, "one hundred plus one" 12 | assert check_command(0, u"478103487120470129") == True, "Any number" 13 | assert check_command(127, u"Checkio") == True, "Uppercase" 14 | assert check_command(7, u"Hello") == False, "Only full match" 15 | assert check_command(8, u"a") == False, "Too short command" 16 | assert check_command(5, u"H2O") == True, "Water" 17 | assert check_command(42, u"C2H5OH") == False, "Yep, this is not the Answer" -------------------------------------------------------------------------------- /scientific expedition/digit-stack.py: -------------------------------------------------------------------------------- 1 | def digit_stack(commands): 2 | sum = 0 3 | q = [] 4 | for command in commands: 5 | if command.startswith('PUSH'): 6 | q.append(int(command.split(' ')[1])) 7 | elif command.startswith('POP'): 8 | try: 9 | sum += q.pop() 10 | except IndexError: 11 | pass 12 | else: 13 | try: 14 | sum += q[-1] 15 | except IndexError: 16 | pass 17 | return sum 18 | 19 | if __name__ == '__main__': 20 | #These "asserts" using only for self-checking and not necessary for auto-testing 21 | assert digit_stack(["PUSH 3", "POP", "POP", "PUSH 4", "PEEK", 22 | "PUSH 9", "PUSH 0", "PEEK", "POP", "PUSH 1", "PEEK"]) == 8, "Example" 23 | assert digit_stack(["POP", "POP"]) == 0, "pop, pop, zero" 24 | assert digit_stack(["PUSH 9", "PUSH 9", "POP"]) == 9, "Push the button" 25 | assert digit_stack([]) == 0, "Nothing" 26 | -------------------------------------------------------------------------------- /loading-cargo.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def f(i, j, data): 5 | if i == 0: 6 | if data[0] <= j: 7 | return data[0] 8 | return 0 9 | if data[i] > j: 10 | return f(i - 1, j, data) 11 | return max(f(i - 1, j, data), f(i - 1, j - data[i], data) + data[i]) 12 | 13 | 14 | def checkio(data): 15 | total = sum(data) 16 | data.sort() 17 | length = len(data) 18 | n = f(length - 1, total / 2, data) 19 | return total - 2 * n 20 | 21 | 22 | #These "asserts" using only for self-checking and not necessary for auto-testing 23 | if __name__ == '__main__': 24 | assert checkio([10, 10]) == 0, "1st example" 25 | assert checkio([10]) == 10, "2nd example" 26 | assert checkio([5, 8, 13, 27, 14]) == 3, "3rd example" 27 | assert checkio([5, 5, 6, 5]) == 1, "4th example" 28 | assert checkio([12, 30, 30, 32, 42, 49]) == 9, "5th example" 29 | assert checkio([1, 1, 1, 3]) == 0, "6th example" 30 | assert checkio([43, 14, 19, 24, 23, 16, 46]) == 1 31 | -------------------------------------------------------------------------------- /home/golden-pyramid.py: -------------------------------------------------------------------------------- 1 | def count_gold(pyramid): 2 | l = [pyramid[0][0]] 3 | for i in range(1, len(pyramid)): 4 | l.append(l[-1] + pyramid[i][-1]) 5 | for j in range(len(pyramid[i])-2, 0, -1): 6 | l[j] = max(l[j], l[j-1])+pyramid[i][j] 7 | l[0] += pyramid[i][0] 8 | return max(l) 9 | 10 | 11 | if __name__ == '__main__': 12 | #These "asserts" using only for self-checking and not necessary for auto-testing 13 | assert count_gold(( 14 | (1,), 15 | (2, 3), 16 | (3, 3, 1), 17 | (3, 1, 5, 4), 18 | (3, 1, 3, 1, 3), 19 | (2, 2, 2, 2, 2, 2), 20 | (5, 6, 4, 5, 6, 4, 3) 21 | )) == 23, "First example" 22 | assert count_gold(( 23 | (1,), 24 | (2, 1), 25 | (1, 2, 1), 26 | (1, 2, 1, 1), 27 | (1, 2, 1, 1, 1), 28 | (1, 2, 1, 1, 1, 1), 29 | (1, 2, 1, 1, 1, 1, 9) 30 | )) == 15, "Second example" 31 | assert count_gold(( 32 | (9,), 33 | (2, 2), 34 | (3, 3, 3), 35 | (4, 4, 4, 4) 36 | )) == 18, "Third example" 37 | -------------------------------------------------------------------------------- /determinant.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | def determinantValue(matrix): 3 | """ 4 | calculate the value of determinant 5 | """ 6 | 7 | matrixLength = len(matrix) 8 | if matrixLength == 1: 9 | return matrix[0][0] 10 | 11 | if matrixLength == 2: 12 | return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0] 13 | 14 | value = 0 15 | for i in range(matrixLength): 16 | sign = 1 17 | if i % 2 == 1: 18 | sign = -1 19 | subMatrix = [] 20 | for j in range(1, matrixLength): 21 | subMatrix.append(matrix[j][0:i] + matrix[j][i + 1:]) 22 | value += sign * determinantValue(subMatrix) * matrix[0][i] 23 | return value 24 | 25 | def checkio(data): 26 | return determinantValue(data) 27 | 28 | #These "asserts" using only for self-checking and not necessary for auto-testing 29 | if __name__ == '__main__': 30 | assert checkio([[4, 3], [6, 3]]) == -6, 'First example' 31 | 32 | assert checkio([[1, 3, 2], 33 | [1, 1, 4], 34 | [2, 2, 1]]) == 14, 'Second example' 35 | -------------------------------------------------------------------------------- /destination-in-spiral.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def position(data): 5 | if data == 1: 6 | return 0, 0 7 | for i in range(1, 10, 2): 8 | if data <= i ** 2: 9 | break 10 | data -= (i - 2) ** 2 + 1 11 | n = i / 2 12 | d, r = data / (i-1), data % (i-1) 13 | if d == 0: 14 | return -n + r + 1, n 15 | if d == 1: 16 | return n, n - r - 1 17 | if d == 2: 18 | return n - r - 1, -n 19 | if d == 3: 20 | return -n, -n + r + 1 21 | return 0, 0 22 | 23 | 24 | def checkio(data): 25 | a, b = data 26 | x1, y1 = position(a) 27 | x2, y2 = position(b) 28 | 29 | return abs(x1 - x2) + abs(y1 - y2) 30 | 31 | #These "asserts" using only for self-checking and not necessary for auto-testing 32 | if __name__ == '__main__': 33 | assert checkio([1, 9]) == 2, "First" 34 | assert checkio([9, 1]) == 2, "Reverse First" 35 | assert checkio([10, 25]) == 1, "Neighbours" 36 | assert checkio([5, 9]) == 4, "Diagonal" 37 | assert checkio([26, 31]) == 5, "One row" 38 | assert checkio([50, 16]) == 10, "One more test" -------------------------------------------------------------------------------- /friendly-number.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def friendly_number(number, base=1000, decimals=0, suffix='', 5 | powers=['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']): 6 | """ 7 | Format a number as friendly text, using common suffixes. 8 | """ 9 | main = float(number) 10 | powerLength = len(powers) 11 | i = 0 12 | while abs(main) >= base and i < powerLength - 1: 13 | main /= base 14 | i += 1 15 | if decimals == 0: 16 | main = int(main) 17 | else: 18 | main = round(main, decimals) 19 | fmt = "%."+str(decimals)+"f"+powers[i]+suffix 20 | ret = fmt % main 21 | return ret 22 | 23 | #These "asserts" using only for self-checking and not necessary for auto-testing 24 | if __name__ == '__main__': 25 | assert friendly_number(102) == '102', '102' 26 | assert friendly_number(10240) == '10k', '10k' 27 | assert friendly_number(12341234, decimals=1) == '12.3M', '12.3M' 28 | assert friendly_number(12461, decimals=1) == '12.5k', '12.5k' 29 | assert friendly_number(1024000000, base=1024, suffix='iB') == '976MiB', '976MiB' 30 | 31 | -------------------------------------------------------------------------------- /scientific expedition/fibonacci-golf.py: -------------------------------------------------------------------------------- 1 | def g(a,b,c,d,e,f,n): 2 | if n==0: 3 | return a 4 | if n==1: 5 | return b 6 | if n==2 and c!=0: 7 | return c 8 | s=d*g(a,b,c,d,e,f,n-1)+e*g(a,b,c,d,e,f,n-2) 9 | if f!=0: 10 | s+=f*g(a,b,c,d,e,f,n-3) 11 | return s 12 | 13 | def fibgolf(t,n): 14 | if t==u'fibonacci': 15 | return g(0,1,0,1,1,0,n) 16 | if t==u'tribonacci': 17 | return g(0,1,1,1,1,1,n) 18 | if t==u'lucas': 19 | return g(2,1,0,1,1,0,n) 20 | if t==u'jacobsthal': 21 | return g(0,1,0,1,2,0,n) 22 | if t==u'pell': 23 | return g(0,1,0,2,1,0,n) 24 | if t==u'perrin': 25 | return g(3,0,2,0,1,1,n) 26 | if t==u'padovan': 27 | return g(0,1,1,0,1,1,n) 28 | return 0 29 | 30 | 31 | if __name__ == '__main__': 32 | assert fibgolf(u'fibonacci', 10) == 55 33 | assert fibgolf(u'tribonacci', 10) == 149 34 | assert fibgolf(u'lucas', 10) == 123 35 | assert fibgolf(u'jacobsthal', 10) == 341 36 | assert fibgolf(u'pell', 10) == 2378 37 | assert fibgolf(u'perrin', 10) == 17 38 | assert fibgolf(u'padovan', 10) == 9 39 | 40 | -------------------------------------------------------------------------------- /mine/call-to-home.py: -------------------------------------------------------------------------------- 1 | from math import ceil 2 | from collections import Counter 3 | 4 | def total_cost(calls): 5 | c = Counter() 6 | for line in calls: 7 | date, time, duration = line.split(' ') 8 | c[date] += int(ceil(float(duration)/60)) 9 | return sum([i > 100 and (i-100)*2+100 or i for i in c.itervalues()]) 10 | 11 | 12 | if __name__ == '__main__': 13 | #These "asserts" using only for self-checking and not necessary for auto-testing 14 | assert total_cost((u"2014-01-01 01:12:13 181", 15 | u"2014-01-02 20:11:10 600", 16 | u"2014-01-03 01:12:13 6009", 17 | u"2014-01-03 12:13:55 200")) == 124, "Base example" 18 | assert total_cost((u"2014-02-05 01:00:00 1", 19 | u"2014-02-05 02:00:00 1", 20 | u"2014-02-05 03:00:00 1", 21 | u"2014-02-05 04:00:00 1")) == 4, "Short calls but money..." 22 | assert total_cost((u"2014-02-05 01:00:00 60", 23 | u"2014-02-05 02:00:00 60", 24 | u"2014-02-05 03:00:00 60", 25 | u"2014-02-05 04:00:00 6000")) == 106, "Precise calls" 26 | -------------------------------------------------------------------------------- /find-ip.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import re 3 | def checkio(text): 4 | """ 5 | find all IPs 6 | """ 7 | ret = [] 8 | data = text.split(' ') 9 | regexp = r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$' 10 | for ip in data: 11 | if re.match(regexp, ip): 12 | flag = True 13 | for n in ip.split('.'): 14 | if int(n) not in range(0, 256): 15 | flag = False 16 | if flag: 17 | ret.append(ip) 18 | return ret 19 | 20 | #These "asserts" using only for self-checking and not necessary for auto-testing 21 | if __name__ == '__main__': 22 | assert checkio("192.168.1.1 and 10.0.0.1 or 127.0.0.1") == \ 23 | ["192.168.1.1", "10.0.0.1", "127.0.0.1"], "All correct" 24 | assert checkio("10.0.0.1.1 but 127.0.0.256 1.1.1.1") == \ 25 | ["1.1.1.1"], "Only 1.1.1.1" 26 | assert checkio("167.11.0.0 1.2.3.255 192,168,1,1") == \ 27 | ["167.11.0.0", "1.2.3.255"], "0 and 255" 28 | assert checkio("267.11.0.0 1.2.3.4/16 192:168:1:1") == \ 29 | [], "I don't see IP" 30 | assert checkio("00250.00001.0000002.1 251.1.2.1") == \ 31 | ["251.1.2.1"], "Be careful with zeros" 32 | -------------------------------------------------------------------------------- /brackets.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(expr): 5 | #replace this for solution 6 | opn = [] 7 | opn.append('#') 8 | for c in expr: 9 | if c in ['(', '[', '{']: 10 | opn.append(c) 11 | elif c == ')': 12 | if opn[-1] == '(': 13 | opn.pop() 14 | else: 15 | return False 16 | elif c == ']': 17 | if opn[-1] == '[': 18 | opn.pop() 19 | else: 20 | return False 21 | elif c == '}': 22 | if opn[-1] == '{': 23 | opn.pop() 24 | else: 25 | return False 26 | if opn[-1] == '#': 27 | return True 28 | return False 29 | 30 | #These "asserts" using only for self-checking and not necessary for auto-testing 31 | if __name__ == '__main__': 32 | assert checkio(u"((5+3)*2+1)") == True, "Simple" 33 | assert checkio(u"{[(3+1)+2]+}") == True, "Different types" 34 | assert checkio(u"(3+{1-1)}") == False, ") is alone inside {}" 35 | assert checkio(u"[1+1]+(2*2)-{3/3}") == True, "Different operators" 36 | assert checkio(u"(({[(((1)-2)+3)-3]/3}-3)") == False, "One is redundant" -------------------------------------------------------------------------------- /scientific expedition/square-spiral.py: -------------------------------------------------------------------------------- 1 | from operator import sub 2 | def position(id): 3 | i, x, y = 0, 0, 0 4 | while (2*i+1)**2 < id: 5 | i += 1 6 | x -= i 7 | y += i 8 | diff = (2*i+1)**2 - id 9 | if diff > 2*i: 10 | diff -= 2*i 11 | y -= 2*i 12 | else: 13 | y -= diff 14 | diff -= diff 15 | if diff > 2*i: 16 | diff -= 2*i 17 | x += 2*i 18 | else: 19 | x += diff 20 | diff -= diff 21 | if diff > 2*i: 22 | diff -= 2*i 23 | y += 2*i 24 | else: 25 | y += diff 26 | diff -= diff 27 | x -= diff 28 | return x, y 29 | 30 | 31 | def find_distance(first, second): 32 | return sum(map(abs, map(sub, position(first), position(second)))) 33 | 34 | if __name__ == '__main__': 35 | #These "asserts" using only for self-checking and not necessary for auto-testing 36 | assert find_distance(1, 9) == 2, "First" 37 | assert find_distance(9, 1) == 2, "Reverse First" 38 | assert find_distance(10, 25) == 1, "Neighbours" 39 | assert find_distance(5, 9) == 4, "Diagonal" 40 | assert find_distance(26, 31) == 5, "One row" 41 | assert find_distance(50, 16) == 10, "One more test" -------------------------------------------------------------------------------- /home/moore_neighbourhood.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | def count_neighbours(grid, row, col): 4 | 5 | g = lambda x, w: filter(lambda z: 0 <= z < w, map(lambda y: x+y, range(-1, 2))) 6 | return sum([grid[x][y] for x in g(row, len(grid)) for y in g(col, len(grid[0])) if x != row or y != col]) 7 | 8 | 9 | if __name__ == '__main__': 10 | # These "asserts" using only for self-checking and not necessary for auto-testing 11 | assert count_neighbours( 12 | ((1, 0, 0, 1, 0), 13 | (0, 1, 0, 0, 0), 14 | (0, 0, 1, 0, 1), 15 | (1, 0, 0, 0, 0), 16 | (0, 0, 1, 0, 0),), 1, 2) == 3, "1st example" 17 | assert count_neighbours(((1, 0, 0, 1, 0), 18 | (0, 1, 0, 0, 0), 19 | (0, 0, 1, 0, 1), 20 | (1, 0, 0, 0, 0), 21 | (0, 0, 1, 0, 0),), 0, 0) == 1, "2nd example" 22 | assert count_neighbours(((1, 1, 1), 23 | (1, 1, 1), 24 | (1, 1, 1),), 0, 2) == 3, "Dense corner" 25 | assert count_neighbours(((0, 0, 0), 26 | (0, 1, 0), 27 | (0, 0, 0),), 1, 1) == 0, "Single" 28 | -------------------------------------------------------------------------------- /electronic station/weak-point.py: -------------------------------------------------------------------------------- 1 | def weak_point(matrix): 2 | m = 10000 3 | minI = 0 4 | minJ = 0 5 | for i, line in enumerate(matrix): 6 | if m > sum(line): 7 | m = sum(line) 8 | minI = i 9 | m = 10000 10 | for j, line in enumerate(zip(*matrix)): 11 | if m > sum(line): 12 | m = sum(line) 13 | minJ = j 14 | return minI, minJ 15 | 16 | 17 | if __name__ == '__main__': 18 | #These "asserts" using only for self-checking and not necessary for auto-testing 19 | assert isinstance(weak_point([[1]]), (list, tuple)), "The result should be a list or a tuple" 20 | assert list(weak_point([[7, 2, 7, 2, 8], 21 | [2, 9, 4, 1, 7], 22 | [3, 8, 6, 2, 4], 23 | [2, 5, 2, 9, 1], 24 | [6, 6, 5, 4, 5]])) == [3, 3], "Example" 25 | assert list(weak_point([[7, 2, 4, 2, 8], 26 | [2, 8, 1, 1, 7], 27 | [3, 8, 6, 2, 4], 28 | [2, 5, 2, 9, 1], 29 | [6, 6, 5, 4, 5]])) == [1, 2], "Two weak point" 30 | assert list(weak_point([[1, 1, 1], 31 | [1, 1, 1], 32 | [1, 1, 1]])) == [0, 0], "Top left" 33 | -------------------------------------------------------------------------------- /mine/broken-clock.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime, timedelta 2 | def broken_clock(starting_time, wrong_time, error_description): 3 | format = '%H:%M:%S' 4 | td = datetime.strptime(wrong_time,format)-datetime.strptime(starting_time, format) 5 | desc = error_description.split(' ') 6 | mis, misUnit, real, realUnit = int(desc[0]), desc[1].rstrip('s'), int(desc[3]), desc[4].rstrip('s') 7 | tdm = eval('timedelta(%ss=%d)'%(misUnit,mis)) 8 | tdr = eval('timedelta(%ss=%d)'%(realUnit,real)) 9 | realtime = td*int(tdr.total_seconds())/int(tdr.total_seconds()+tdm.total_seconds())+datetime.strptime(starting_time, format) 10 | return realtime.strftime(format) 11 | 12 | 13 | #These "asserts" using only for self-checking and not necessary for auto-testing 14 | if __name__ == "__main__": 15 | assert broken_clock('00:00:00', '00:00:15', '+5 seconds at 10 seconds') == '00:00:10', "First example" 16 | assert broken_clock('06:10:00', '06:10:15', '-5 seconds at 10 seconds') == '06:10:30', 'Second example' 17 | assert broken_clock('13:00:00', '14:01:00', '+1 second at 1 minute') == '14:00:00', 'Third example' 18 | assert broken_clock('01:05:05', '04:05:05', '-1 hour at 2 hours') == '07:05:05', 'Fourth example' 19 | assert broken_clock('00:00:00', '00:00:30', '+2 seconds at 6 seconds') == '00:00:22', 'Fifth example' 20 | -------------------------------------------------------------------------------- /painting-wall.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(num, data): 5 | painted = [] 6 | for k, i in enumerate(data): 7 | painted.append(i[:]) 8 | painted.sort(key=lambda i: i[0]) 9 | j = 0 10 | for l in range(len(painted) - 1): 11 | if painted[j][1] >= painted[j + 1][0]: 12 | painted[j][1] = max(painted[j][1], painted[j + 1][1]) 13 | painted.pop(j + 1) 14 | else: 15 | j += 1 16 | length = 0 17 | for l in painted: 18 | length += l[1] - l[0] + 1 19 | if length >= num: 20 | return k + 1 21 | return -1 22 | 23 | 24 | if __name__ == '__main__': 25 | #These "asserts" using only for self-checking and not necessary for auto-testing 26 | checkio(20, [[1, 2], [20, 30], [25, 28], [5, 10], [4, 21], [1, 6]]) 27 | assert checkio(5, [[1, 5], [11, 15], [2, 14], [21, 25]]) == 1, "1st" 28 | assert checkio(6, [[1, 5], [11, 15], [2, 14], [21, 25]]) == 2, "2nd" 29 | assert checkio(11, [[1, 5], [11, 15], [2, 14], [21, 25]]) == 3, "3rd" 30 | assert checkio(16, [[1, 5], [11, 15], [2, 14], [21, 25]]) == 4, "4th" 31 | assert checkio(21, [[1, 5], [11, 15], [2, 14], [21, 25]]) == -1, "not enough" 32 | assert checkio(1000000011, [[1, 1000000000], [11, 1000000010]]) == -1, "large" -------------------------------------------------------------------------------- /area-of-a-convex-polygon.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | def areaOfTriangleDot(d1, d2, d3): 3 | return areaOfTriangleVector((d2[0]-d1[0], d2[1]-d1[1]), (d3[0]-d1[0], d3[1]-d1[1])) 4 | 5 | 6 | def areaOfTriangleVector(e1, e2): 7 | return abs((e1[1]*e2[0]-e2[1]*e1[0])/2.0) 8 | 9 | 10 | def checkio(data): 11 | basePoint = [data.pop(0)] 12 | length = len(data) 13 | ret = sum(map(areaOfTriangleDot, basePoint*(length-1), data[:length-1], data[1:length])) 14 | return ret 15 | 16 | if __name__ == '__main__': 17 | #This part is using only for self-checking and not necessary for auto-testing 18 | def almost_equal(checked, correct, significant_digits=1): 19 | precision = 0.1 ** significant_digits 20 | return correct - precision < checked < correct + precision 21 | 22 | assert almost_equal(checkio([[1, 1], [9, 9], [9, 1]]), 32), "The half of the square" 23 | assert almost_equal(checkio([[4, 10], [7, 1], [1, 4]]), 22.5), "Triangle" 24 | assert almost_equal(checkio([[1, 2], [3, 8], [9, 8], [7, 1]]), 40), "Quadrilateral" 25 | assert almost_equal(checkio([[3, 3], [2, 7], [5, 9], [8, 7], [7, 3]]), 26), "Pentagon" 26 | assert almost_equal(checkio([[7, 2], [3, 2], [1, 5], [3, 9], [7, 9], [9, 6]]), 42), "Hexagon" 27 | assert almost_equal(checkio([[4, 1], [3, 4], [3, 7], [4, 8], [7, 9], [9, 6], [7, 1]]), 35.5), "Heptagon" 28 | -------------------------------------------------------------------------------- /electronic station/moria-doors.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | def similarity(word1, word2): 5 | s = 0.0 6 | if word1[0] == word2[0]: 7 | s += 0.1 8 | if word1[-1] == word2[-1]: 9 | s += 0.1 10 | if len(word1) > len(word2): 11 | s += 0.3*len(word2)/len(word1) 12 | else: 13 | s += 0.3*len(word1)/len(word2) 14 | s1 = set(word1) 15 | s2 = set(word2) 16 | s += 0.5*len(s1.intersection(s2))/len(s1.union(s2)) 17 | return s 18 | 19 | 20 | def find_word(message): 21 | message = [s for s in re.compile(r"\W").split(message.lower()) if s][::-1] 22 | return max(message, key=lambda i: sum([similarity(i, j) for j in message])) 23 | 24 | if __name__ == '__main__': 25 | #These "asserts" using only for self-checking and not necessary for auto-testing 26 | assert find_word(u"Speak friend and enter.") == "friend", "Friend" 27 | assert find_word(u"Beard and Bread") == "bread", "Bread is Beard" 28 | assert find_word(u"The Doors of Durin, Lord of Moria. Speak friend and enter. " 29 | u"I Narvi made them. Celebrimbor of Hollin drew these signs") == "durin", "Durin" 30 | assert find_word(u"Aoccdrnig to a rscheearch at Cmabrigde Uinervtisy." 31 | u" According to a researcher at Cambridge University.") == "according", "Research" 32 | assert find_word(u"One, two, two, three, three, three.") == "three", "Repeating" 33 | -------------------------------------------------------------------------------- /box-probability.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | from fractions import Fraction 3 | 4 | 5 | def formatFloat(c): 6 | if int(c) == c: 7 | return int(c) 8 | 9 | fmt = '%.2f' % c 10 | if fmt[-1] == '0': 11 | return float(fmt[:-1]) 12 | 13 | return float(fmt) 14 | 15 | 16 | def checkio(marbles, step): 17 | parts = [(marbles.count('b'), marbles.count('w'), 1)] 18 | length = len(marbles) 19 | for i in range(step - 1): 20 | newParts = [] 21 | for j in parts: 22 | b, w, c = j 23 | if b != 0: 24 | newParts.append((b - 1, w + 1, Fraction(b, length) * c)) 25 | if w != 0: 26 | newParts.append((b + 1, w - 1, Fraction(w, length) * c)) 27 | parts = newParts 28 | ret = 0 29 | for i in parts: 30 | b, w, c = i 31 | ret += Fraction(w, length) * c 32 | print formatFloat(float(ret)) 33 | return formatFloat(float(ret)) 34 | 35 | #These "asserts" using only for self-checking and not necessary for auto-testing 36 | if __name__ == '__main__': 37 | assert checkio(u'bbw', 3) == 0.48, "1st example" 38 | assert checkio(u'wwb', 3) == 0.52, "2nd example" 39 | assert checkio(u'www', 3) == 0.56, "3rd example" 40 | assert checkio(u'bbbb', 1) == 0, "4th example" 41 | assert checkio(u'wwbb', 4) == 0.5, "5th example" 42 | assert checkio(u'bwbwbwb', 5) == 0.48, "6th example" 43 | -------------------------------------------------------------------------------- /scientific expedition/network-attack.py: -------------------------------------------------------------------------------- 1 | def capture(matrix): 2 | num = len(matrix) 3 | visited = [] 4 | time = [10000000] * num 5 | time[0] = 0 6 | now = 0 7 | while len(visited) != num - 1: 8 | visited.append(now) 9 | neighbors = [i for i in range(num) if matrix[now][i] == 1 and i not in visited] 10 | for n in neighbors: 11 | if time[now] + matrix[n][n] < time[n]: 12 | time[n] = time[now] + matrix[n][n] 13 | now = min([(i, time[i]) for i in range(num) if i not in visited], key=lambda a: a[1])[0] 14 | return max(time) 15 | 16 | 17 | if __name__ == '__main__': 18 | # These "asserts" using only for self-checking and not necessary for auto-testing 19 | assert capture([[0, 1, 0, 1, 0, 1], 20 | [1, 8, 1, 0, 0, 0], 21 | [0, 1, 2, 0, 0, 1], 22 | [1, 0, 0, 1, 1, 0], 23 | [0, 0, 0, 1, 3, 1], 24 | [1, 0, 1, 0, 1, 2]]) == 8, "Base example" 25 | assert capture([[0, 1, 0, 1, 0, 1], 26 | [1, 1, 1, 0, 0, 0], 27 | [0, 1, 2, 0, 0, 1], 28 | [1, 0, 0, 1, 1, 0], 29 | [0, 0, 0, 1, 3, 1], 30 | [1, 0, 1, 0, 1, 2]]) == 4, "Low security" 31 | assert capture([[0, 1, 1], 32 | [1, 9, 1], 33 | [1, 1, 9]]) == 9, "Small" 34 | -------------------------------------------------------------------------------- /digits-doublets.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | def editDistance(a, b): 4 | a = str(a) 5 | b = str(b) 6 | ret = 0 7 | for i in range(len(a)): 8 | if a[i] != b[i]: 9 | ret += 1 10 | return ret 11 | 12 | 13 | def checkio(numbers): 14 | start = numbers[0] 15 | end = numbers[-1] 16 | closed = [] 17 | status = dict() 18 | now = start 19 | status[now] = -1 20 | opn = [now] 21 | while now != end: 22 | opn.remove(now) 23 | closed.append(now) 24 | neighbors = [x for x in numbers if editDistance(now, x) == 1] 25 | for n in neighbors: 26 | if n in closed: 27 | continue 28 | if n not in opn: 29 | opn.append(n) 30 | status[n] = now 31 | now = opn[0] 32 | l = [] 33 | while status[now] != -1: 34 | l.insert(0, now) 35 | now = status[now] 36 | l.insert(0, now) 37 | return l 38 | 39 | #These "asserts" using only for self-checking and not necessary for auto-testing 40 | if __name__ == '__main__': 41 | assert checkio([123, 991, 323, 321, 329, 121, 921, 125, 999]) == [123, 121, 921, 991, 999], "First" 42 | assert checkio([111, 222, 333, 444, 555, 666, 121, 727, 127, 777]) == [111, 121, 127, 727, 777], "Second" 43 | assert checkio([456, 455, 454, 356, 656, 654]) == [456, 454, 654], "Third, [456, 656, 654] is correct too" 44 | 45 | 46 | -------------------------------------------------------------------------------- /home/how-to-find-friends.py: -------------------------------------------------------------------------------- 1 | def check_connection(network, first, second): 2 | d = dict() 3 | for i in network: 4 | p1, p2 = i.split('-') 5 | d.setdefault(p1, []).append(p2) 6 | d.setdefault(p2, []).append(p1) 7 | opn = [first] 8 | cls = [] 9 | while len(opn): 10 | now = opn.pop() 11 | cls.append(now) 12 | if now == second: 13 | return True 14 | for next in d.setdefault(now, []): 15 | if next not in cls and next not in opn: 16 | opn.append(next) 17 | return False 18 | 19 | 20 | if __name__ == '__main__': 21 | #These "asserts" using only for self-checking and not necessary for auto-testing 22 | assert check_connection( 23 | ("dr101-mr99", "mr99-out00", "dr101-out00", "scout1-scout2", 24 | "scout3-scout1", "scout1-scout4", "scout4-sscout", "sscout-super"), 25 | "scout2", "scout3") == True, "Scout Brotherhood" 26 | assert check_connection( 27 | ("dr101-mr99", "mr99-out00", "dr101-out00", "scout1-scout2", 28 | "scout3-scout1", "scout1-scout4", "scout4-sscout", "sscout-super"), 29 | "super", "scout2") == True, "Super Scout" 30 | assert check_connection( 31 | ("dr101-mr99", "mr99-out00", "dr101-out00", "scout1-scout2", 32 | "scout3-scout1", "scout1-scout4", "scout4-sscout", "sscout-super"), 33 | "dr101", "sscout") == False, "I don't know any scouts." 34 | -------------------------------------------------------------------------------- /number-guess.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | shots = [3, 5, 7] 3 | 4 | 5 | def checkio(attempts): 6 | times = len(attempts) 7 | if times < 4: 8 | return [shots[times - 1], 1] 9 | n = 70 * attempts[1][0] + 21 * attempts[2][0] + 15 * attempts[3][0] 10 | while n > 100: 11 | n -= 105 12 | return [2, n] 13 | 14 | 15 | if __name__ == '__main__': 16 | #This part is using only for self-checking and not necessary for auto-testing 17 | MAX_ATTEMPT = 8 18 | 19 | def initial_referee(data): 20 | data["attempt_count"] = 0 21 | data["guess"] = 0 22 | return data 23 | 24 | def check_solution(func, goal, initial): 25 | prev_steps = [initial] 26 | for attempt in range(MAX_ATTEMPT): 27 | divisor, guess = func(prev_steps[:]) 28 | if guess == goal: 29 | return True 30 | if divisor <= 1 or divisor > 10: 31 | print("You gave wrong divisor range.") 32 | return False 33 | if guess < 1 or guess > 100: 34 | print("You gave wrong guess number range.") 35 | return False 36 | prev_steps.append((goal % divisor, divisor)) 37 | print("Too many attempts.") 38 | return False 39 | 40 | assert check_solution(checkio, 47, (2, 5)), "1st example" 41 | assert check_solution(checkio, 94, (3, 7)), "1st example" 42 | assert check_solution(checkio, 52, (0, 2)), "1st example" 43 | -------------------------------------------------------------------------------- /home/the-flat-dictionary.py: -------------------------------------------------------------------------------- 1 | def flatten(dictionary): 2 | stack = [((), dictionary)] 3 | result = {} 4 | while stack: 5 | path, current = stack.pop() 6 | for k, v in current.items(): 7 | if isinstance(v, dict) and v: 8 | stack.append((path + (k,), v)) 9 | elif not v: 10 | result["/".join((path + (k,)))] = "" 11 | else: 12 | result["/".join((path + (k,)))] = v 13 | return result 14 | 15 | 16 | if __name__ == '__main__': 17 | #These "asserts" using only for self-checking and not necessary for auto-testing 18 | assert flatten({"key": "value"}) == {"key": "value"}, "Simple" 19 | assert flatten( 20 | {"key": {"deeper": {"more": {"enough": "value"}}}} 21 | ) == {"key/deeper/more/enough": "value"}, "Nested" 22 | assert flatten({"empty": {}}) == {"empty": ""}, "Empty value" 23 | assert flatten({"name": { 24 | "first": "One", 25 | "last": "Drone"}, 26 | "job": "scout", 27 | "recent": {}, 28 | "additional": { 29 | "place": { 30 | "zone": "1", 31 | "cell": "2"}}} 32 | ) == {"name/first": "One", 33 | "name/last": "Drone", 34 | "job": "scout", 35 | "recent": "", 36 | "additional/place/zone": "1", 37 | "additional/place/cell": "2"} -------------------------------------------------------------------------------- /shortest-knight-path.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import itertools 3 | 4 | 5 | def char2int(c): 6 | return ord(c) - ord('a') + 1 7 | 8 | 9 | def checkio(cells): 10 | """str -> int 11 | Number of moves in the shortest path of knight 12 | """ 13 | src, des = cells.split('-') 14 | src = char2int(src[0]), int(src[1]) 15 | des = char2int(des[0]), int(des[1]) 16 | dirs = list(itertools.product([2, -2], [1, -1])) 17 | dirs.extend(list(itertools.product([1, -1], [2, -2]))) 18 | opn = [] 19 | closed = [] 20 | status = dict() 21 | now = src 22 | status[now] = 0 23 | while now != des: 24 | closed.append(now) 25 | for d in dirs: 26 | newP = (now[0] + d[0], now[1] + d[1]) 27 | if newP[0] in range(1, 9) and newP[1] in range(1, 9): 28 | if newP in closed: 29 | continue 30 | if newP in opn: 31 | continue 32 | opn.append(newP) 33 | status[newP] = status[now] + 1 34 | now = opn.pop(0) 35 | 36 | return status[now] 37 | 38 | 39 | if __name__ == "__main__": 40 | #These "asserts" using only for self-checking and not necessary for auto-testing 41 | assert checkio(u"b1-d5") == 2, "1st example" 42 | assert checkio(u"a6-b8") == 1, "2nd example" 43 | assert checkio(u"h1-g2") == 4, "3rd example" 44 | assert checkio(u"h8-d7") == 3, "4th example" 45 | assert checkio(u"a1-h8") == 6, "5th example" -------------------------------------------------------------------------------- /ore-in-the-desert.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import itertools 3 | import random 4 | 5 | candidates = None 6 | 7 | def checkio(previous): 8 | global candidates 9 | times = len(previous) 10 | if times == 0: 11 | candidates = list(itertools.product(range(10), repeat=2)) 12 | candidates.remove((0, 0)) 13 | return [0, 0] 14 | 15 | p = previous[-1] 16 | remove = [] 17 | for d in candidates: 18 | if round(((d[0] - p[0]) ** 2 + (d[1] - p[1]) ** 2) ** .5) != p[2]: 19 | remove.append(d) 20 | for r in remove: 21 | candidates.remove(r) 22 | c = random.choice(candidates) 23 | return c 24 | 25 | 26 | if __name__ == '__main__': 27 | #This part is using only for self-testing. 28 | def check_solution(func, ore): 29 | recent_data = [] 30 | for step in range(4): 31 | row, col = func([d[:] for d in recent_data]) # copy the list 32 | if row < 0 or row > 9 or col < 0 or col > 9: 33 | print("Where is our probe?") 34 | return False 35 | if (row, col) == ore: 36 | return True 37 | dist = round(((row - ore[0]) ** 2 + (col - ore[1]) ** 2) ** 0.5) 38 | recent_data.append([row, col, dist]) 39 | print("It was the last probe.") 40 | return False 41 | 42 | assert check_solution(checkio, (1, 1)), "Example" 43 | assert check_solution(checkio, (9, 9)), "Bottom right" 44 | assert check_solution(checkio, (6, 6)), "Center" 45 | -------------------------------------------------------------------------------- /cakes-rows.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import itertools 3 | 4 | def hashLine(line): 5 | ls = [] 6 | for l in line: 7 | ls.append(str(l[0])) 8 | ls.append(str(l[1])) 9 | return ''.join(ls) 10 | 11 | 12 | def isLine(triple): 13 | c1, c2, c3 = triple 14 | x1, y1 = c1 15 | x2, y2 = c2 16 | x3, y3 = c3 17 | if (y2 - y1) * (x3 - x2) == (y3 - y2) * (x2 - x1): 18 | return True 19 | return False 20 | 21 | 22 | def checkio(cakes): 23 | lines = [c for c in itertools.combinations(cakes, 3) if isLine(c)] 24 | d = dict() 25 | for i, line in enumerate(lines): 26 | d[hashLine(line)] = i 27 | for i in range(len(lines)-1): 28 | for j in range(i, len(lines)): 29 | s1 = set() 30 | for k in lines[i]: 31 | s1.add(tuple(k)) 32 | s2 = set() 33 | for k in lines[j]: 34 | s2.add(tuple(k)) 35 | if len(s1.intersection(s2)) == 2: 36 | m = min(d[hashLine(lines[i])], d[hashLine(lines[j])]) 37 | d[hashLine(lines[i])] = m 38 | d[hashLine(lines[j])] = m 39 | n = len(set(d.values())) 40 | 41 | return n 42 | 43 | #These "asserts" using only for self-checking and not necessary for auto-testing 44 | if __name__ == '__main__': 45 | assert checkio([[3, 3], [5, 5], [8, 8], [2, 8], [8, 2]]) == 2 46 | assert checkio( 47 | [[2, 2], [2, 5], [2, 8], [5, 2], [7, 2], [8, 2], 48 | [9, 2], [4, 5], [4, 8], [7, 5], [5, 8], [9, 8]]) == 6 -------------------------------------------------------------------------------- /hidden-word.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(text, word): 5 | w = len(word) 6 | text = text.replace(' ', '').split('\n') 7 | for x in range(len(text)): 8 | for y in range(len(text[x]) - w + 1): 9 | if text[x][y:y + w].lower() == word: 10 | return [x + 1, y + 1, x + 1, y + w] 11 | for x in range(len(text) - w + 1): 12 | for y in range(len(text[x])): 13 | try: 14 | if ''.join([line[y] for line in text[x:x + w]]).lower() == word: 15 | return [x + 1, y + 1, x + w, y + 1] 16 | except BaseException: 17 | continue 18 | return [1, 1, 1, 4] 19 | 20 | #These "asserts" using only for self-checking and not necessary for auto-testing 21 | if __name__ == '__main__': 22 | assert checkio(u"""DREAMING of apples on a wall, 23 | And dreaming often, dear, 24 | I dreamed that, if I counted all, 25 | -How many would appear?""", u"ten") == [2, 14, 2, 16] 26 | assert checkio(u"""He took his vorpal sword in hand: 27 | Long time the manxome foe he sought-- 28 | So rested he by the Tumtum tree, 29 | And stood awhile in thought. 30 | And as in uffish thought he stood, 31 | The Jabberwock, with eyes of flame, 32 | Came whiffling through the tulgey wood, 33 | And burbled as it came!""", u"noir") == [4, 16, 7, 16] 34 | assert checkio(u"""Twas brillig, and the slithy toves 35 | Did gyre and gimble in the wabe; 36 | All mimsy were the borogoves, 37 | And the mome raths outgrabe.""", 38 | u"stog") == [1,19,4,19] -------------------------------------------------------------------------------- /elementary/friends.py: -------------------------------------------------------------------------------- 1 | class Friends: 2 | def __init__(self, connections): 3 | self.__friends = list(connections) 4 | 5 | def add(self, connection): 6 | if connection in self.__friends: 7 | return False 8 | self.__friends.append(connection) 9 | return True 10 | 11 | def remove(self, connection): 12 | try: 13 | self.__friends.remove(connection) 14 | return True 15 | except ValueError: 16 | return False 17 | 18 | def names(self): 19 | return reduce(set.union, self.__friends) 20 | 21 | def connected(self, name): 22 | s = reduce(set.union, [f for f in self.__friends if name in f], set()) 23 | s.discard(name) 24 | return s 25 | 26 | 27 | 28 | if __name__ == '__main__': 29 | #These "asserts" using only for self-checking and not necessary for auto-testing 30 | letter_friends = Friends(({"a", "b"}, {"b", "c"}, {"c", "a"}, {"a", "c"})) 31 | digit_friends = Friends([{"1", "2"}, {"3", "1"}]) 32 | assert letter_friends.add({"c", "d"}) is True, "Add" 33 | assert letter_friends.add({"c", "d"}) is False, "Add again" 34 | assert letter_friends.remove({"c", "d"}) is True, "Remove" 35 | assert digit_friends.remove({"c", "d"}) is False, "Remove non exists" 36 | assert letter_friends.names() == {"a", "b", "c"}, "Names" 37 | assert letter_friends.connected("d") == set(), "Non connected name" 38 | assert letter_friends.connected("a") == {"b", "c"}, "Connected name" 39 | print letter_friends.connected("a") 40 | -------------------------------------------------------------------------------- /elementary/building-base.py: -------------------------------------------------------------------------------- 1 | class Building: 2 | def __init__(self, south, west, width_WE, width_NS, height=10): 3 | self.__s = south 4 | self.__w = west 5 | self.__wwe = width_WE 6 | self.__wns = width_NS 7 | self.__h = height 8 | self.__c = {} 9 | 10 | def corners(self): 11 | self.__c['north-east'] = [self.__s+self.__wns, self.__w+self.__wwe] 12 | self.__c['south-east'] = [self.__s, self.__w+self.__wwe] 13 | self.__c['south-west'] = [self.__s, self.__w] 14 | self.__c['north-west'] = [self.__s+self.__wns, self.__w] 15 | return self.__c 16 | 17 | def area(self): 18 | return self.__wwe*self.__wns 19 | 20 | def volume(self): 21 | return self.__wwe*self.__wns*self.__h 22 | 23 | def __repr__(self): 24 | return "Building(%r, %r, %r, %r, %r)" % (self.__s, self.__w, self.__wwe, self.__wns, self.__h) 25 | 26 | 27 | if __name__ == '__main__': 28 | #These "asserts" using only for self-checking and not necessary for auto-testing 29 | def json_dict(d): 30 | return dict((k, list(v)) for k, v in d.items()) 31 | 32 | b = Building(1, 2, 2, 3) 33 | b2 = Building(1, 2, 2, 3, 5) 34 | assert json_dict(b.corners()) == {'north-east': [4, 4], 'south-east': [1, 4], 35 | 'south-west': [1, 2], 'north-west': [4, 2]}, "Corners" 36 | assert b.area() == 6, "Area" 37 | assert b.volume() == 60, "Volume" 38 | assert b2.volume() == 30, "Volume2" 39 | assert str(b) == "Building(1, 2, 2, 3, 10)", "String" 40 | -------------------------------------------------------------------------------- /numbered-triangles.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import itertools 3 | 4 | 5 | def check(chips, chip_order, rotation_order): 6 | total = 0 7 | for i in range(len(chips)): 8 | chip = chips[chip_order[i]] 9 | rotation = rotation_order[i] 10 | prev_chip = chips[chip_order[i - 1]] 11 | prev_rotation = rotation_order[i - 1] 12 | if chip[rotation[0]] != prev_chip[prev_rotation[1]]: 13 | return 0 14 | total += chip[rotation[2]] 15 | return total 16 | 17 | def checkio(chips): 18 | perm = set(r if r[0] < r[-1] else r[::-1] for r in itertools.permutations(range(1, 6), 5)) 19 | chip_orders = [[0] + list(r) for r in perm] 20 | 21 | rotation = itertools.permutations(range(3), 3) 22 | rotation_orders = list(itertools.product(rotation, repeat=6)) 23 | 24 | return max(check(chips, chip_order, rotation_order) for chip_order in chip_orders for rotation_order in rotation_orders) 25 | 26 | #These "asserts" using only for self-checking and not necessary for auto-testing 27 | 28 | 29 | if __name__ == '__main__': 30 | assert checkio( 31 | [[1, 4, 20], [3, 1, 5], [50, 2, 3], 32 | [5, 2, 7], [7, 5, 20], [4, 7, 50]]) == 152, "First" 33 | assert checkio( 34 | [[1, 10, 2], [2, 20, 3], [3, 30, 4], 35 | [4, 40, 5], [5, 50, 6], [6, 60, 1]]) == 210, "Second" 36 | assert checkio( 37 | [[1, 2, 3], [2, 1, 3], [4, 5, 6], 38 | [6, 5, 4], [5, 1, 2], [6, 4, 3]]) == 21, "Third" 39 | assert checkio( 40 | [[5, 9, 5], [9, 6, 9], [6, 7, 6], 41 | [7, 8, 7], [8, 1, 8], [1, 2, 1]]) == 0, "Fourth" -------------------------------------------------------------------------------- /speechmodule.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | FIRST_TEN = ["zero", "one", "two", "three", "four", "five", "six", "seven", 4 | "eight", "nine"] 5 | SECOND_TEN = ["ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", 6 | "sixteen", "seventeen", "eighteen", "nineteen"] 7 | OTHER_TENS = ["twenty", "thirty", "forty", "fifty", "sixty", "seventy", 8 | "eighty", "ninety"] 9 | HUNDRED = "hundred" 10 | 11 | 12 | def checkio(number): 13 | if number == 0: 14 | return FIRST_TEN[0] 15 | units = number%10 16 | number/=10 17 | decades = number%10 18 | number/=10 19 | hundreds = number%10 20 | strList = [] 21 | if hundreds!=0: 22 | strList.append(FIRST_TEN[hundreds]) 23 | strList.append(HUNDRED) 24 | if decades == 0: 25 | strList.append(FIRST_TEN[units]) 26 | elif decades == 1: 27 | strList.append(SECOND_TEN[units]) 28 | else: 29 | strList.append(OTHER_TENS[decades-2]) 30 | if units != 0: 31 | strList.append(FIRST_TEN[units]) 32 | return ' '.join(strList) 33 | 34 | #Some hints 35 | #Don't forget strip whitespaces at the end of string 36 | 37 | 38 | #These "asserts" using only for self-checking and not necessary for auto-testing 39 | if __name__ == '__main__': 40 | assert checkio(4) == 'four', "1st example" 41 | assert checkio(133) == 'one hundred thirty three', "2nd example" 42 | assert checkio(12) == 'twelve', "3rd example" 43 | assert checkio(101) == 'one hundred one', "4th example" 44 | assert checkio(212) == 'two hundred twelve', "5th example" 45 | assert checkio(40) == 'forty', "6th example" 46 | -------------------------------------------------------------------------------- /auto-painting.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | def checkio(capacity, number): 4 | if number <= capacity: 5 | return ','.join([''.join('0123456789'[:number])]*2) 6 | s = '0123456789'[:number]*2 7 | return ','.join([s[i:i+capacity] for i in range(0, number*2, capacity)]) 8 | 9 | 10 | if __name__ == '__main__': 11 | #This part is using only for self-checking and not necessary for auto-testing 12 | def check_solution(func, k, n, max_steps): 13 | result = func(k, n) 14 | actions = result.split(",") 15 | if len(actions) > max_steps: 16 | print("It can be shorter.") 17 | return False 18 | details = [0] * n 19 | for act in actions: 20 | if len(act) > k: 21 | print("The system can contain {0} detail(s).".format(k)) 22 | return False 23 | if len(set(act)) < len(act): 24 | print("You can not place one detail twice in one load") 25 | return False 26 | for ch in act: 27 | details[int(ch)] += 1 28 | if any(d < 2 for d in details): 29 | print("I see no painted details.") 30 | return False 31 | if any(d > 2 for d in details): 32 | print("I see over painted details.") 33 | return False 34 | return True 35 | 36 | assert check_solution(checkio, 2, 3, 3), "1st Example" 37 | assert check_solution(checkio, 6, 3, 2), "2nd Example" 38 | assert check_solution(checkio, 3, 6, 4), "3rd Example" 39 | assert check_solution(checkio, 1, 4, 8), "4th Example" 40 | assert check_solution(checkio, 2, 5, 5), "5th Example" 41 | -------------------------------------------------------------------------------- /mathematically-lucky-tickets.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import operator 3 | from fractions import Fraction 4 | 5 | OPERATORS = { 6 | '+': operator.add, 7 | '-': operator.sub, 8 | '*': operator.mul, 9 | '/': operator.div 10 | }.items() 11 | 12 | 13 | def checkio(ticket): 14 | subresults = {} 15 | 16 | def calculate(start, end): 17 | p = (start, end) 18 | if p not in subresults: 19 | n = ticket[start:end + 1] 20 | sr = subresults[p] = {int(n): n} 21 | for s in xrange(start, end): 22 | for op_name, op_func in OPERATORS: 23 | for r1, e1 in calculate(start, s).items(): 24 | for r2, e2 in calculate(s + 1, end).items(): 25 | try: 26 | res = op_func(Fraction(r1), Fraction(r2)) 27 | except ZeroDivisionError: 28 | continue 29 | if res not in sr: 30 | sr[res] = '(%s %s %s)' % (e1, op_name, e2) 31 | return subresults[p] 32 | 33 | results = calculate(0, len(ticket) - 1) 34 | if 100 in results: 35 | return False 36 | else: 37 | return True 38 | 39 | #These "asserts" using only for self-checking and not necessary for auto-testing 40 | if __name__ == '__main__': 41 | assert checkio(u'000000') == True, "All zeros" 42 | assert checkio(u'707409') == True, "You can not transform it to 100" 43 | assert checkio(u'595347') == False, "(5 + ((9 / (3 / 34)) - 7)) = 100" 44 | assert checkio(u'271353') == False, "(2 - (7 * (((1 / 3) - 5) * 3))) = 100" 45 | assert checkio(u"100478") == True 46 | assert checkio(u"836403") == False 47 | -------------------------------------------------------------------------------- /determine-the-order.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(data): 5 | syms = set() 6 | rulesSmaller = {} 7 | for word in data: 8 | for sym in word: 9 | syms.add(sym) 10 | 11 | for sym in syms: 12 | rulesSmaller.setdefault(sym, set()) 13 | 14 | for word in data: 15 | for i in range(len(word) - 1): 16 | if word[i] != word[i + 1]: 17 | rulesSmaller[word[i + 1]].add(word[i]) 18 | 19 | parts = [] 20 | for sym in syms: 21 | if len(rulesSmaller[sym]) == 0: 22 | parts.append(sym) 23 | 24 | visited = [] 25 | while len(visited) != len(syms): 26 | while len(parts) != 0: 27 | now = min(parts) 28 | visited.append(now) 29 | parts.remove(now) 30 | 31 | for i in rulesSmaller: 32 | if now in rulesSmaller[i]: 33 | rulesSmaller[i].remove(now) 34 | for i in [x for x in syms if x not in visited]: 35 | if len(rulesSmaller[i]) == 0: 36 | parts.append(i) 37 | 38 | return ''.join(visited) 39 | 40 | 41 | #These "asserts" using only for self-checking and not necessary for auto-testing 42 | if __name__ == '__main__': 43 | assert checkio(["acb", "bd", "zwa"]) == "zwacbd",\ 44 | "Just concatenate it" 45 | assert checkio(["klm", "kadl", "lsm"]) == "kadlsm",\ 46 | "Paste in" 47 | assert checkio(["a", "b", "c"]) == "abc",\ 48 | "Cant determine the order - use english alphabet" 49 | assert checkio(["aazzss"]) == "azs",\ 50 | "Each symbol only once" 51 | assert checkio(["dfg", "frt", "tyg"]) == "dfrtyg",\ 52 | "Concatenate and paste in" 53 | assert checkio(["hello", "low", "lino", "itttnosw"]) == "helitnosw" 54 | 55 | -------------------------------------------------------------------------------- /calculate-islands.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import itertools 3 | 4 | def getAround(x, y, width, length): 5 | px = [x+i for i in range(-1, 2) if x+i in range(0, width)] 6 | py = [y+i for i in range(-1, 2) if y+i in range(0, length)] 7 | return list(itertools.product(px, py)) 8 | 9 | 10 | def checkio(data): 11 | width = len(data) 12 | length = len(data[0]) 13 | unvisited = [(x, y) for x in range(width) for y in range(length)] 14 | islands = [] 15 | while unvisited: 16 | x, y = unvisited.pop(0) 17 | if data[x][y]: 18 | count = 1 19 | toGo = getAround(x, y, width, length) 20 | while toGo: 21 | i = toGo.pop(0) 22 | if i in unvisited: 23 | unvisited.remove(i) 24 | if data[i[0]][i[1]]: 25 | count += 1 26 | toGo.extend(getAround(i[0], i[1], width, length)) 27 | islands.append(count) 28 | islands.sort() 29 | return islands 30 | 31 | #These "asserts" using only for self-checking and not necessary for auto-testing 32 | if __name__ == '__main__': 33 | assert checkio([[0, 0, 0, 0, 0], 34 | [0, 0, 1, 1, 0], 35 | [0, 0, 0, 1, 0], 36 | [0, 1, 0, 0, 0], 37 | [0, 0, 0, 0, 0]]) == [1, 3], "1st example" 38 | assert checkio([[0, 0, 0, 0, 0], 39 | [0, 0, 1, 1, 0], 40 | [0, 0, 0, 1, 0], 41 | [0, 1, 1, 0, 0]]) == [5], "2nd example" 42 | assert checkio([[0, 0, 0, 0, 0, 0], 43 | [1, 0, 0, 1, 1, 1], 44 | [1, 0, 0, 0, 0, 0], 45 | [0, 0, 1, 1, 1, 0], 46 | [0, 0, 0, 0, 0, 0], 47 | [0, 1, 1, 1, 1, 0], 48 | [0, 0, 0, 0, 0, 0]]) == [2, 3, 3, 4], "3rd example" 49 | -------------------------------------------------------------------------------- /mono-captcha.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | FONT = [[0,1,1,0,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,0,1,1,0,1,1,1,0,1,1,1,0,0,1,1,0], 3 | [0,1,0,1,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,1,0,1,0,1,0], 4 | [0,1,0,1,0,0,1,0,0,0,1,1,0,0,1,0,0,1,1,1,0,1,1,0,0,1,1,1,0,0,1,0,0,1,1,1,0,1,1,1,0], 5 | [0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0], 6 | [0,0,1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,0,0,1,0,1,1,0,0,0,1,1,0,1,0,0,0,1,1,1,0,1,1,0,0]] 7 | 8 | def getNum(n): 9 | return [line[4*n+1:4*n+4] for line in FONT] 10 | 11 | 12 | def diff(image, font): 13 | count = 0 14 | for i in range(5): 15 | for j in range(3): 16 | if image[i][j] != font[i][j]: 17 | count+=1 18 | return count 19 | 20 | 21 | 22 | 23 | def checkio(image): 24 | n = len(image[0])/4 25 | ret = [] 26 | for i in range(n): 27 | num = [line[4*i+1:4*i+4] for line in image] 28 | diffDict = dict() 29 | for i in range(10): 30 | diffDict[i] = diff(num, getNum(i)) 31 | ret.append(sorted(diffDict.items(), key=lambda x:x[1])[0][0]) 32 | return int(''.join([str(x) for x in ret])) 33 | 34 | #These "asserts" using only for self-checking and not necessary for auto-testing 35 | if __name__ == '__main__': 36 | assert checkio([[0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0], 37 | [0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0], 38 | [0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0], 39 | [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0], 40 | [0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0]]) == 394, "394 clear" 41 | assert checkio([[0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0], 42 | [0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0], 43 | [0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0], 44 | [0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0], 45 | [0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0]]) == 394, "again 394 but with noise" 46 | -------------------------------------------------------------------------------- /mine/hexagon-spiral.py: -------------------------------------------------------------------------------- 1 | from operator import sub 2 | 3 | def locate(n): 4 | """ 5 | Here we use three dimensions (x, y, z) to locate a number. 6 | The coordinate of 1 is (0, 0, 0). 7 | The positive direction of x is 1->7. 8 | The positive direction of y is 7->2. 9 | The positive direction of z is 2->1. 10 | """ 11 | l, x, y, z = 0, 0, 0, 0 12 | # determine the level n belongs 13 | while 6 * l * (l + 1) / 2 + 1 < n: 14 | l += 1 15 | #backtrace 16 | diff = 6 * l * (l + 1) / 2 + 1 - n 17 | x = l 18 | if diff <= l: 19 | z += diff 20 | return x, y, z 21 | diff -= l 22 | z += l 23 | if diff <= l: 24 | x -= diff 25 | return x, y, z 26 | diff -= l 27 | x -= l 28 | if diff <= l: 29 | y += diff 30 | return x, y, z 31 | diff -= l 32 | y += l 33 | if diff <= l: 34 | z -= diff 35 | return x, y, z 36 | diff -= l 37 | z -= l 38 | if diff <= l: 39 | x += diff 40 | return x, y, z 41 | diff -= l 42 | x += l 43 | y -= diff 44 | 45 | return x, y, z 46 | 47 | 48 | def distance(a, b): 49 | """ 50 | This method calculate the distance between two point 51 | """ 52 | dx, dy, dz = map(sub, a, b) 53 | #use x, y to represent the distance 54 | x = dx - dz 55 | y = dy - dz 56 | #if x, y has the same sign 57 | if x * y > 0: 58 | return abs(x + y) - min(abs(x), abs(y)) 59 | return abs(x) + abs(y) 60 | 61 | 62 | def hex_spiral(first, second): 63 | return distance(locate(first), locate(second)) 64 | 65 | #These "asserts" using only for self-checking and not necessary for auto-testing 66 | if __name__ == '__main__': 67 | assert hex_spiral(2, 9) == 1, "First" 68 | assert hex_spiral(9, 2) == 1, "Reverse First" 69 | assert hex_spiral(6, 19) == 2, "Second, short way" 70 | assert hex_spiral(5, 11) == 3, "Third" 71 | assert hex_spiral(13, 15) == 2, "Fourth, One row" 72 | assert hex_spiral(11, 17) == 4, "Fifth, One more test" 73 | -------------------------------------------------------------------------------- /the-square-chest.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def getEdges(start, width): 5 | ret = [] 6 | for i in range(width): 7 | ret.append([start + i, start + i + 1]) 8 | ret.append([start + 4 * width + i, start + 4 * width + i + 1]) 9 | ret.append([start + 4 * i, start + 4 * i + 4]) 10 | ret.append([start + width + 4 * i, start + width + 4 * i + 4]) 11 | return ret 12 | 13 | 14 | def checkio(lines_list): 15 | """Return the quantity of squares""" 16 | for l in lines_list: 17 | if l[0] > l[1]: 18 | l[0], l[1] = l[1], l[0] 19 | count = 0 20 | for width in range(1, 4): 21 | for i in range(4 - width): 22 | for j in range((4 - width)): 23 | isIn = True 24 | edges = getEdges(4 * i + j + 1, width) 25 | for e in edges: 26 | if e not in lines_list: 27 | isIn = False 28 | break 29 | if isIn: 30 | count += 1 31 | return count 32 | 33 | 34 | if __name__ == '__main__': 35 | # assert (checkio([[1, 2], [3, 4], [1, 5], [2, 6], [4, 8], [5, 6], [6, 7], 36 | # [7, 8], [6, 10], [7, 11], [8, 12], [10, 11], 37 | # [10, 14], [12, 16], [14, 15], [15, 16]]) == 3), "First, from description" 38 | # assert (checkio([[1, 2], [2, 3], [3, 4], [1, 5], [4, 8], 39 | # [6, 7], [5, 9], [6, 10], [7, 11], [8, 12], 40 | # [9, 13], [10, 11], [12, 16], [13, 14], [14, 15], [15, 16]]) == 2), "Second, from description" 41 | # assert (checkio([[1, 2], [1, 5], [2, 6], [5, 6]]) == 1), "Third, one small square" 42 | # assert (checkio([[1, 2], [1, 5], [2, 6], [5, 9], [6, 10], [9, 10]]) == 0), "Fourth, it's not square" 43 | # assert (checkio([[16, 15], [16, 12], [15, 11], [11, 10], 44 | # [10, 14], [14, 13], [13, 9]]) == 0), "Fifth, snake" 45 | assert ( 46 | checkio([[16, 15], [16, 12], [15, 11], [11, 12], [11, 10], [10, 14], [9, 10], [14, 13], [13, 9], [15, 14]]) == 3) -------------------------------------------------------------------------------- /three-points-circle.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def isInt(x): 5 | return float(round(x)) == x 6 | 7 | 8 | def checkio(data): 9 | """ 10 | assume two points are p0(x0,y0), p1(x1,y1) 11 | the middle point is (mx, my) = ((x0+x1)/2, (y0+y1)/2) 12 | the slope k is dy/dx = (y1-y0)/(x1-x0) 13 | so the slope of midperpendicular is -dx/dy 14 | midperpendicular function is dy*(y-my)+dx*(x-mx)=0 15 | i.e. y = (dy*my-dx*x+dx*mx)/dy 16 | so we got two midperpendicular functions 17 | y = (dy01*my01-dx01*x+dx01*mx01)/dy01 18 | y = (dy02*my02-dx02*x+dx02*mx02)/dy02 19 | then we can calculate the center of circle as 20 | x = (dx01*dy02*mx01+dx01*dx02*my01-dx02*dy01*my02-dx02*dy01*mx02)/(-dx02*dy01+dx01*dy02) 21 | """ 22 | (x0, y0), (x1, y1), (x2, y2) = eval(data) 23 | dx01, dy01 = x0 - x1, y0 - y1 24 | dx02, dy02 = x0 - x2, y0 - y2 25 | mx01, my01 = (x0 + x1) / 2.0, (y0 + y1) / 2.0 26 | mx02, my02 = (x0 + x2) / 2.0, (y0 + y2) / 2.0 27 | x = (dy01 * dy02 * my01 + dx01 * dy02 * mx01 - dy02 * dy01 * my02 - dx02 * dy01 * mx02) / ( 28 | - dx02 * dy01 + dx01 * dy02) 29 | y = 0 30 | if dy01 != 0: 31 | y = (dy01 * my01 - dx01 * x + dx01 * mx01) / dy01 32 | elif dy02 != 0: 33 | y = (dy02 * my02 - dx02 * x + dx02 * mx02) / dy02 34 | else: 35 | print "can not build a circle" 36 | r = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5 37 | print x, y, r 38 | ret = "" 39 | if isInt(x): 40 | ret += "(x-%d)^2+" % round(x) 41 | else: 42 | ret += "(x-%.3g)^2+" % x 43 | if isInt(y): 44 | ret += "(y-%d)^2=" % round(y) 45 | else: 46 | ret += "(y-%.3g)^2=" % y 47 | if isInt(r): 48 | ret += "%d^2" % round(r) 49 | else: 50 | ret += "%.3g^2" % r 51 | return ret 52 | 53 | #These "asserts" using only for self-checking and not necessary for auto-testing 54 | if __name__ == '__main__': 55 | assert checkio(u"(2,2),(6,2),(2,6)") == "(x-4)^2+(y-4)^2=2.83^2" 56 | assert checkio(u"(3,7),(6,9),(9,7)") == "(x-6)^2+(y-5.75)^2=3.25^2" 57 | -------------------------------------------------------------------------------- /convex-hull.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def cmp(d1, d2): 5 | if d1[0] > d2[0]: 6 | return 1 7 | if d1[0] < d2[0]: 8 | return -1 9 | if d1[1] > d2[1]: 10 | return 1 11 | if d1[1] < d2[1]: 12 | return -1 13 | return 0 14 | 15 | 16 | def checkio(dots): 17 | """list[list[int, int],] -> list[int,] 18 | Find the convex hull. 19 | """ 20 | data = sorted(dots, cmp=cmp) 21 | basePoint = data.pop(0) 22 | ret = [basePoint] 23 | vx = (0, 1) 24 | dotProduct = [] 25 | for d in data: 26 | vector = (d[0] - basePoint[0], d[1] - basePoint[1]) 27 | dotProduct.append( 28 | (round((vx[0] * vector[0] + vx[1] * vector[1]) / (vector[0] ** 2 + vector[1] ** 2) ** .5, 2), d)) 29 | dotProduct.sort(key=lambda x: x[0], reverse=True) 30 | last = dotProduct[-1][0] 31 | for i in dotProduct[::-1]: 32 | if i[0] != last: 33 | break 34 | data = dotProduct[:dotProduct.index(i)+1] 35 | data.extend(dotProduct[:dotProduct.index(i):-1]) 36 | data = [i[1] for i in data] 37 | ret.append(data.pop(0)) 38 | for d in data: 39 | while len(ret) > 1: 40 | p = ret[-1] 41 | p2 = ret[-2] 42 | v1 = p2[0] - p[0], p2[1] - p[1] 43 | v2 = p[0] - d[0], p[1] - d[1] 44 | if v1[0] * v2[1] - v1[1] * v2[0] > 0: 45 | ret.pop(-1) 46 | else: 47 | break 48 | ret.append(d) 49 | 50 | return [dots.index(r) for r in ret] 51 | 52 | 53 | if __name__ == '__main__': 54 | #These "asserts" using only for self-checking and not necessary for auto-testing 55 | # assert checkio( 56 | # [[7, 6], [8, 4], [7, 2], [3, 2], [1, 6], [1, 8], [4, 9]] 57 | # ) == [4, 5, 6, 0, 1, 2, 3], "First example" 58 | # assert checkio( 59 | # [[3, 8], [1, 6], [6, 2], [7, 6], [5, 5], [8, 4], [6, 8]] 60 | # ) == [1, 0, 6, 3, 5, 2], "Second example" 61 | # assert checkio([[7, 4], [5, 2], [4, 7], [4, 1], [3, 6], [1, 4]]) == [5, 4, 2, 0, 1, 3] 62 | assert checkio([[2,6],[5,5],[4,4],[2,2]]) == [3, 0, 1, 2] -------------------------------------------------------------------------------- /colder-warmer.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import itertools 3 | import random 4 | 5 | candidates = None 6 | 7 | 8 | def edist(x1, y1, x2, y2): 9 | return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** .5 10 | 11 | 12 | def checkio(steps): 13 | global candidates 14 | if len(steps) == 1: 15 | candidates = list(itertools.product(range(10), repeat=2)) 16 | return [0, 0] 17 | 18 | prex, prey = steps[-2][0], steps[-2][1] 19 | nowx, nowy, dis = steps[-1] 20 | for x, y in candidates[:]: 21 | if dis == 0: 22 | if edist(prex, prey, x, y) != edist(nowx, nowy, x, y): 23 | candidates.remove((x, y)) 24 | if dis == -1: 25 | if edist(prex, prey, x, y) >= edist(nowx, nowy, x, y): 26 | candidates.remove((x, y)) 27 | if dis == 1: 28 | if edist(prex, prey, x, y) <= edist(nowx, nowy, x, y): 29 | candidates.remove((x, y)) 30 | ret = random.choice(candidates) 31 | candidates.remove(ret) 32 | return list(ret) 33 | 34 | 35 | if __name__ == '__main__': 36 | #This part is using only for self-checking and not necessary for auto-testing 37 | from math import hypot 38 | 39 | MAX_STEP = 12 40 | 41 | def check_solution(func, goal, start): 42 | prev_steps = [start] 43 | for step in range(MAX_STEP): 44 | row, col = func([s[:] for s in prev_steps]) 45 | if [row, col] == goal: 46 | return True 47 | if 10 <= row or 0 > row or 10 <= col or 0 > col: 48 | print("You gave wrong coordinates.") 49 | return False 50 | prev_distance = hypot(prev_steps[-1][0] - goal[0], prev_steps[-1][1] - goal[1]) 51 | distance = hypot(row - goal[0], col - goal[1]) 52 | alteration = 0 if prev_distance == distance else (1 if prev_distance > distance else -1) 53 | prev_steps.append([row, col, alteration]) 54 | print("Too many steps") 55 | return False 56 | 57 | assert check_solution(checkio, [7, 7], [5, 5, 0]), "1st example" 58 | assert check_solution(checkio, [5, 6], [0, 0, 0]), "2nd example" 59 | -------------------------------------------------------------------------------- /url-normalization.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import re 3 | 4 | r = dict() 5 | for i in range(0x41, 0x5A + 1): 6 | r[i] = chr(ord('a') + i - 0x41) 7 | for i in range(0x61, 0x7A + 1): 8 | r[i] = chr(ord('a') + i - 0x61) 9 | for i in range(0x30, 0x39 + 1): 10 | r[i] = str(i-0x30) 11 | r[0x2d] = '-' 12 | r[0x2e] = '.' 13 | r[0x5f] = '_' 14 | r[0x7e] = '~' 15 | 16 | 17 | def trans(m): 18 | num = int(m.group()[1:], 16) 19 | if num in r.keys(): 20 | return r[num] 21 | else: 22 | return m.group().upper() 23 | 24 | 25 | def normalize(s): 26 | if len(s) == 0: 27 | return s 28 | pattern = '%\w{2}' 29 | return re.sub(pattern, trans, s) 30 | 31 | 32 | def checkio(url): 33 | p = url.lower().split('/', 3) 34 | ret = 'http://' 35 | print p 36 | if p[2].split(':')[-1] == '80': 37 | ret += p[2].split(':')[0] 38 | else: 39 | ret += p[2] 40 | if len(p) == 3: 41 | return ret 42 | 43 | l = [] 44 | ret += '/' 45 | for i in p[3].split('/'): 46 | if i == '.': 47 | continue 48 | elif i == '..': 49 | l.pop(-1) 50 | else: 51 | l.append(normalize(i)) 52 | path = '/'.join(l) 53 | ret += path 54 | return ret 55 | 56 | #These "asserts" using only for self-checking and not necessary for auto-testing 57 | if __name__ == '__main__': 58 | assert checkio(u"Http://Www.Checkio.org") ==\ 59 | "http://www.checkio.org", "1st rule" 60 | assert checkio(u"http://www.checkio.org/%cc%b1bac") ==\ 61 | "http://www.checkio.org/%CC%B1bac", "2nd rule" 62 | assert checkio(u"http://www.checkio.org/task%5F%31") ==\ 63 | "http://www.checkio.org/task_1", "3rd rule" 64 | assert checkio(u"http://www.checkio.org:80/home/") ==\ 65 | "http://www.checkio.org/home/", "4th rule" 66 | assert checkio(u"http://www.checkio.org:8080/home/") ==\ 67 | "http://www.checkio.org:8080/home/", "4th rule again" 68 | assert checkio(u"http://www.checkio.org/task/./1/../2/././name") ==\ 69 | "http://www.checkio.org/task/2/name", "5th rule" 70 | print('First set of tests done') 71 | -------------------------------------------------------------------------------- /disposable-teleports.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(teleports_string): 5 | route = ['1'] 6 | portals = dict() 7 | for i in teleports_string.split(','): 8 | portals.setdefault(i[0], []).append(i[1]) 9 | portals.setdefault(i[1], []).append(i[0]) 10 | pre = 0 11 | while len(set(route)) != len(portals) or route[-1] != '1': 12 | current = route[-1] 13 | open = [x for x in portals[current] if x > pre] 14 | if not open: 15 | route.pop(-1) 16 | pre = current 17 | portals[pre].append(route[-1]) 18 | portals[route[-1]].append(pre) 19 | 20 | else: 21 | m = min(open) 22 | route.append(m) 23 | portals[m].remove(current) 24 | portals[current].remove(m) 25 | pre = 0 26 | return ''.join(route) 27 | 28 | #This part is using only for self-testing 29 | if __name__ == "__main__": 30 | def check_solution(func, teleports_str): 31 | route = func(teleports_str) 32 | teleports_map = [tuple(sorted([int(x), int(y)])) for x, y in teleports_str.split(",")] 33 | if route[0] != '1' or route[-1] != '1': 34 | print("The path must start and end at 1") 35 | return False 36 | ch_route = route[0] 37 | for i in range(len(route) - 1): 38 | teleport = tuple(sorted([int(route[i]), int(route[i + 1])])) 39 | if not teleport in teleports_map: 40 | print("No way from {0} to {1}".format(route[i], route[i + 1])) 41 | return False 42 | teleports_map.remove(teleport) 43 | ch_route += route[i + 1] 44 | for s in range(1, 9): 45 | if not str(s) in ch_route: 46 | print("You forgot about {0}".format(s)) 47 | return False 48 | return True 49 | 50 | assert check_solution(checkio, "12,23,34,45,56,67,78,81"), "First" 51 | assert check_solution(checkio, "12,28,87,71,13,14,34,35,45,46,63,65"), "Second" 52 | assert check_solution(checkio, "12,15,16,23,24,28,83,85,86,87,71,74,56"), "Third" 53 | assert check_solution(checkio, "13,14,23,25,34,35,47,56,58,76,68"), "Fourth" -------------------------------------------------------------------------------- /radiation-search.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | from collections import Counter 3 | 4 | 5 | def merge(tree, src, dest): 6 | matrixLength = len(tree) 7 | for x in range(matrixLength): 8 | for y in range(matrixLength): 9 | if tree[x][y] == src: 10 | tree[x][y] = dest 11 | 12 | 13 | def checkio(matrix): 14 | matrixLength = len(matrix) 15 | mergeTree = [[x + y * matrixLength for x in range(matrixLength)] for y in range(matrixLength)] 16 | for x in range(matrixLength): 17 | for y in range(matrixLength): 18 | if x != matrixLength - 1: 19 | if matrix[x][y] == matrix[x + 1][y] and mergeTree[x + 1][y] != mergeTree[x][y]: 20 | merge(mergeTree, mergeTree[x + 1][y], mergeTree[x][y]) 21 | if x != 0: 22 | if matrix[x][y] == matrix[x - 1][y] and mergeTree[x - 1][y] != mergeTree[x][y]: 23 | merge(mergeTree, mergeTree[x - 1][y], mergeTree[x][y]) 24 | if y != matrixLength - 1: 25 | if matrix[x][y] == matrix[x][y + 1] and mergeTree[x][y + 1] != mergeTree[x][y]: 26 | merge(mergeTree, mergeTree[x][y + 1], mergeTree[x][y]) 27 | if y != 0: 28 | if matrix[x][y] == matrix[x][y - 1] and mergeTree[x][y - 1] != mergeTree[x][y]: 29 | merge(mergeTree, mergeTree[x][y - 1], mergeTree[x][y]) 30 | cnt = Counter() 31 | for x in range(matrixLength): 32 | for y in range(matrixLength): 33 | cnt[mergeTree[x][y]] += 1 34 | index, times = cnt.most_common(1)[0] 35 | return [times, matrix[index / matrixLength][index % matrixLength]] 36 | 37 | #These "asserts" using only for self-checking and not necessary for auto-testing 38 | if __name__ == '__main__': 39 | assert checkio([ 40 | [1, 2, 3, 4, 5], 41 | [1, 1, 1, 2, 3], 42 | [1, 1, 1, 2, 2], 43 | [1, 2, 2, 2, 1], 44 | [1, 1, 1, 1, 1] 45 | ]) == [14, 1], "14 of 1" 46 | 47 | assert checkio([ 48 | [2, 1, 2, 2, 2, 4], 49 | [2, 5, 2, 2, 2, 2], 50 | [2, 5, 4, 2, 2, 2], 51 | [2, 5, 2, 2, 4, 2], 52 | [2, 4, 2, 2, 2, 2], 53 | [2, 2, 4, 4, 2, 2] 54 | ]) == [19, 2], '19 of 2' -------------------------------------------------------------------------------- /scientific expedition/life-counter.py: -------------------------------------------------------------------------------- 1 | def life_counter(state, tick_n): 2 | lives = set() 3 | for i in range(len(state)): 4 | for j in range(len(state[0])): 5 | if state[i][j] == 1: 6 | lives.add((i, j)) 7 | neighbors = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] 8 | for i in range(tick_n): 9 | die = set() 10 | born = set() 11 | nei = set() 12 | for p in lives: 13 | nei.update([((p[0]+n[0]), (p[1]+n[1])) for n in neighbors]) 14 | if sum([1 for n in neighbors if ((p[0]+n[0]), (p[1]+n[1])) in lives]) not in [2, 3]: 15 | die.add(p) 16 | for p in nei: 17 | if p not in lives and sum([1 for n in neighbors if ((p[0]+n[0]), (p[1]+n[1])) in lives]) == 3: 18 | born.add(p) 19 | lives.difference_update(die) 20 | lives.update(born) 21 | 22 | return len(lives) 23 | 24 | 25 | if __name__ == '__main__': 26 | # These "asserts" using only for self-checking and not necessary for auto-testing 27 | print life_counter(((0, 1, 0), (0, 0, 1), (1, 1, 1)), 999) 28 | assert life_counter(((0, 1, 0, 0, 0, 0, 0), 29 | (0, 0, 1, 0, 0, 0, 0), 30 | (1, 1, 1, 0, 0, 0, 0), 31 | (0, 0, 0, 0, 0, 1, 1), 32 | (0, 0, 0, 0, 0, 1, 1), 33 | (0, 0, 0, 0, 0, 0, 0), 34 | (1, 1, 1, 0, 0, 0, 0)), 4) == 15, "Example" 35 | assert life_counter(((0, 1, 0, 0, 0, 0, 0), 36 | (0, 0, 1, 0, 0, 0, 0), 37 | (1, 1, 1, 0, 0, 0, 0), 38 | (0, 0, 0, 0, 0, 1, 1), 39 | (0, 0, 0, 0, 0, 1, 1), 40 | (0, 0, 0, 0, 0, 0, 0), 41 | (1, 1, 1, 0, 0, 0, 0)), 15) == 14, "Little later" 42 | assert life_counter(((0, 1, 0), 43 | (0, 0, 1), 44 | (1, 1, 1)), 50) == 5, "Glider" 45 | assert life_counter(((1, 1, 0, 1, 1), 46 | (1, 1, 0, 1, 1), 47 | (0, 0, 0, 0, 0), 48 | (1, 1, 0, 1, 1), 49 | (1, 1, 0, 1, 1)), 100) == 16, "Stones" 50 | -------------------------------------------------------------------------------- /cipher-crossword.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import itertools 3 | 4 | 5 | def checkio(crossword, words): 6 | crossword2 = zip(*crossword) 7 | numDict = dict() 8 | for i in range(5): 9 | for j in range(5): 10 | if crossword[i][j] != 0: 11 | numDict.setdefault(crossword[i][j], 0) 12 | if i % 2 == 0 and j % 2 == 0: 13 | numDict[crossword[i][j]] += 2 14 | else: 15 | numDict[crossword[i][j]] += 1 16 | wordDict = dict() 17 | rWordDict = dict() 18 | for w in words: 19 | for c in w: 20 | wordDict.setdefault(c, 0) 21 | wordDict[c] += 1 22 | for i in wordDict: 23 | rWordDict.setdefault(wordDict[i], []).append(i) 24 | solution = dict() 25 | for i in range(0, 5, 2): 26 | cw = itertools.product(rWordDict[numDict[crossword[i][0]]], rWordDict[numDict[crossword[i][1]]], 27 | rWordDict[numDict[crossword[i][2]]], rWordDict[numDict[crossword[i][3]]], 28 | rWordDict[numDict[crossword[i][4]]]) 29 | for c in cw: 30 | if ''.join(c) in words: 31 | for j in range(5): 32 | solution[crossword[i][j]] = c[j] 33 | cw = itertools.product(rWordDict[numDict[crossword2[i][0]]], rWordDict[numDict[crossword2[i][1]]], 34 | rWordDict[numDict[crossword2[i][2]]], rWordDict[numDict[crossword2[i][3]]], 35 | rWordDict[numDict[crossword2[i][4]]]) 36 | for c in cw: 37 | if ''.join(c) in words: 38 | for j in range(5): 39 | solution[crossword2[i][j]] = c[j] 40 | 41 | ret = [] 42 | for i in range(5): 43 | ret.append([]) 44 | for j in range(5): 45 | if crossword[i][j] == 0: 46 | ret[i].append(' ') 47 | else: 48 | ret[i].append(solution[crossword[i][j]]) 49 | return ret 50 | 51 | 52 | if __name__ == '__main__': 53 | assert checkio( 54 | [ 55 | [21, 6, 25, 25, 17], 56 | [14, 0, 6, 0, 2], 57 | [1, 11, 16, 1, 17], 58 | [11, 0, 16, 0, 5], 59 | [26, 3, 14, 20, 6] 60 | ], 61 | ['hello', 'habit', 'lemma', 'ozone', 'bimbo', 'trace'] 62 | ) == [['h', 'e', 'l', 'l', 'o'], 63 | ['a', ' ', 'e', ' ', 'z'], 64 | ['b', 'i', 'm', 'b', 'o'], 65 | ['i', ' ', 'm', ' ', 'n'], 66 | ['t', 'r', 'a', 'c', 'e']] 67 | -------------------------------------------------------------------------------- /digging-a-canal.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | from operator import add 3 | 4 | def checkio(data): 5 | dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)] 6 | width = len(data) 7 | height = len(data[0]) 8 | 9 | k = 0 10 | opn = [(0, j) for j in range(height) if data[0][j] == 0] 11 | dig = [(0, j) for j in range(height) if data[0][j] == 1] 12 | cls = [] 13 | while True: 14 | while opn: 15 | now = opn.pop(0) 16 | cls.append(now) 17 | if now[0] == width - 1: 18 | return k 19 | for d in dirs: 20 | nxt = tuple(map(add, now, d)) 21 | if nxt[0] in range(0, width) and nxt[1] in range(0, height): 22 | if nxt in cls: 23 | continue 24 | if nxt in opn: 25 | continue 26 | if data[nxt[0]][nxt[1]] == 0: 27 | opn.append(nxt) 28 | else: 29 | dig.append(nxt) 30 | k += 1 31 | opn = dig 32 | dig = [] 33 | 34 | return 0 35 | 36 | 37 | #These "asserts" using only for self-checking and not necessary for auto-testing 38 | if __name__ == '__main__': 39 | assert checkio([[1, 1, 1, 1, 0, 1, 1], 40 | [1, 1, 1, 1, 0, 0, 1], 41 | [1, 1, 1, 1, 1, 0, 1], 42 | [1, 1, 0, 1, 1, 0, 1], 43 | [1, 1, 0, 1, 1, 1, 1], 44 | [1, 0, 0, 1, 1, 1, 1], 45 | [1, 0, 1, 1, 1, 1, 1]]) == 2, "1st example" 46 | assert checkio([[0, 0, 0, 0, 0, 0, 0], 47 | [1, 1, 1, 1, 1, 1, 1], 48 | [1, 1, 1, 1, 1, 1, 1], 49 | [1, 1, 1, 1, 1, 1, 1], 50 | [1, 1, 0, 1, 0, 1, 1], 51 | [1, 0, 0, 0, 0, 0, 1], 52 | [0, 0, 0, 0, 0, 0, 0]]) == 3, "2nd example" 53 | assert checkio([[1, 1, 1, 1, 1, 0, 1, 1], 54 | [1, 0, 1, 1, 1, 0, 1, 1], 55 | [1, 0, 1, 0, 1, 0, 1, 0], 56 | [1, 0, 1, 1, 1, 0, 1, 1], 57 | [0, 0, 1, 1, 0, 0, 0, 0], 58 | [1, 0, 1, 1, 1, 1, 1, 1], 59 | [1, 0, 1, 1, 1, 1, 1, 1], 60 | [1, 1, 1, 0, 1, 1, 1, 1]]) == 2, "3rd example" 61 | assert checkio( 62 | [[0, 1, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0], [1, 1, 1, 1, 1, 1, 1, 0], 63 | [1, 1, 0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 0, 1, 1, 0], [0, 1, 1, 1, 0, 0, 0, 0]]) == 0 -------------------------------------------------------------------------------- /how-much-gold.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | from fractions import Fraction 4 | 5 | METALS = ('gold', 'tin', 'iron', 'copper') 6 | 7 | 8 | def determinantValue(matrix): 9 | """ 10 | calculate the value of determinant 11 | """ 12 | 13 | matrixLength = len(matrix) 14 | if matrixLength == 2: 15 | return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0] 16 | 17 | value = 0 18 | for i in range(matrixLength): 19 | sign = 1 20 | if i % 2 == 1: 21 | sign = -1 22 | subMatrix = [] 23 | for j in range(1, matrixLength): 24 | subMatrix.append(matrix[j][0:i] + matrix[j][i + 1:]) 25 | value += sign * determinantValue(subMatrix) * matrix[0][i] 26 | return value 27 | 28 | 29 | def checkio(alloys): 30 | """ 31 | Find proportion of gold 32 | """ 33 | matrix = [] 34 | right = [] 35 | for item in alloys: 36 | vector = [0 for x in range(4)] 37 | first, second = item.split('-') 38 | proportion = alloys[item] 39 | for (k, i) in enumerate(METALS): 40 | if i == first or i == second: 41 | vector[k] = proportion.denominator 42 | right.append(proportion.numerator) 43 | matrix.append(vector) 44 | vector = [1 for x in range(4)] 45 | matrix.append(vector) 46 | right.append(1) 47 | denominator = determinantValue(matrix) 48 | 49 | for i in range(4): 50 | matrix[i][0] = right[i] 51 | numerator = determinantValue(matrix) 52 | 53 | return Fraction(numerator, denominator) 54 | 55 | 56 | # this is a better answer 57 | # def checkio(alloys): 58 | # """ 59 | # Find proportion of gold 60 | # """ 61 | # # According to description all test are solvable so let's find other 3 sums 62 | # for alloy in alloys.copy(): 63 | # alloys['-'.join(set(METALS)-set(alloy.split('-')))] = \ 64 | # 1 - alloys[alloy] 65 | # # Now just calculate the proportion of gold from all three proportions that 66 | # # includes 'gold' 67 | # return (sum([alloys[x] for x in alloys if 'gold' in x]) - 1) / 2 68 | 69 | 70 | #These "asserts" using only for self-checking and not necessary for auto-testing 71 | if __name__ == '__main__': 72 | assert checkio({ 73 | 'gold-tin': Fraction(1, 2), 74 | 'gold-iron': Fraction(1, 3), 75 | 'gold-copper': Fraction(1, 4), 76 | }) == Fraction(1, 24), "1/24 of gold" 77 | assert checkio({ 78 | 'tin-iron': Fraction(1, 2), 79 | 'iron-copper': Fraction(1, 2), 80 | 'copper-tin': Fraction(1, 2), 81 | }) == Fraction(1, 4), "quarter" 82 | assert checkio({ 83 | "iron-tin": Fraction(2, 3), 84 | "iron-copper": Fraction(1, 4), 85 | "iron-gold": Fraction(1, 2), 86 | }) == Fraction(7, 24) 87 | -------------------------------------------------------------------------------- /water-jars.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def checkio(first, second, goal): 5 | #replace this for solution 6 | actions = { 7 | "01": lambda f, s: (first, s), 8 | "02": lambda f, s: (f, second), 9 | "12": lambda f, s: ( 10 | f - (second - s if f > second - s else f), 11 | second if f > second - s else s + f), 12 | "21": lambda f, s: ( 13 | first if s > first - f else s + f, 14 | s - (first - f if s > first - f else s), 15 | ), 16 | "10": lambda f, s: (0, s), 17 | "20": lambda f, s: (f, 0) 18 | } 19 | f, s = 0, 0 20 | opn = [] 21 | closed = [] 22 | father = dict() 23 | now = (f, s) 24 | father[now] = None 25 | while now[0] != goal and now[1] != goal: 26 | closed.append(now) 27 | for k in actions.keys(): 28 | f, s = actions[k](now[0], now[1]) 29 | if (f, s) in closed: 30 | continue 31 | if (f, s) in opn: 32 | continue 33 | opn.append((f, s)) 34 | father[(f, s)] = (now, k) 35 | now = opn.pop(0) 36 | 37 | ret = [] 38 | while father[now]: 39 | ret.append(father[now][1]) 40 | now = father[now][0] 41 | return ret[::-1] 42 | 43 | if __name__ == '__main__': 44 | #This part is using only for self-checking and not necessary for auto-testing 45 | def check_solution(func, initial_data, max_steps): 46 | first_volume, second_volume, goal = initial_data 47 | actions = { 48 | "01": lambda f, s: (first_volume, s), 49 | "02": lambda f, s: (f, second_volume), 50 | "12": lambda f, s: ( 51 | f - (second_volume - s if f > second_volume - s else f), 52 | second_volume if f > second_volume - s else s + f), 53 | "21": lambda f, s: ( 54 | first_volume if s > first_volume - f else s + f, 55 | s - (first_volume - f if s > first_volume - f else s), 56 | ), 57 | "10": lambda f, s: (0, s), 58 | "20": lambda f, s: (f, 0) 59 | } 60 | first, second = 0, 0 61 | result = func(*initial_data) 62 | if len(result) > max_steps: 63 | print("You answer contains too many steps. It can be shorter.") 64 | return False 65 | for act in result: 66 | if act not in actions.keys(): 67 | print("I don't know this action {0}".format(act)) 68 | return False 69 | first, second = actions[act](first, second) 70 | if goal == first or goal == second: 71 | return True 72 | print("You did not reach the goal.") 73 | return False 74 | 75 | assert check_solution(checkio, (5, 7, 6), 10), "Example" 76 | assert check_solution(checkio, (3, 4, 1), 2), "One and two" 77 | -------------------------------------------------------------------------------- /hubspot-amulet.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | from copy import deepcopy 3 | from itertools import product 4 | from math import ceil 5 | 6 | 7 | def determinantValue(matrix): 8 | """ 9 | calculate the value of determinant 10 | """ 11 | 12 | matrixLength = len(matrix) 13 | if matrixLength == 2: 14 | return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0] 15 | 16 | value = 0 17 | for i in range(matrixLength): 18 | sign = 1 19 | if i % 2 == 1: 20 | sign = -1 21 | subMatrix = [] 22 | for j in range(1, matrixLength): 23 | subMatrix.append(matrix[j][0:i] + matrix[j][i + 1:]) 24 | value += sign * determinantValue(subMatrix) * matrix[0][i] 25 | return value 26 | 27 | 28 | def checkio(matrix): 29 | matrix = [[matrix[j][i] for j in range(3)] for i in range(3)] 30 | d = determinantValue(matrix) 31 | n = int(ceil(max([sum(line) for line in matrix])/2.0)) 32 | for c in product(range(-n, n+1), repeat=3): 33 | ret = [] 34 | for i in range(3): 35 | m = deepcopy(matrix) 36 | m[0][i] = 0 + c[0] * 360 37 | m[1][i] = 225 + c[1] * 360 38 | m[2][i] = 315 + c[2] * 360 39 | d2 = determinantValue(m) 40 | if d2 % d != 0 or -180 > d2 / d or d2 / d > 180: 41 | break 42 | ret.append(d2 / d) 43 | if len(ret) == 3: 44 | return ret 45 | return [0, 0, 0] 46 | 47 | #These "asserts" using only for self-checking and not necessary for auto-testing 48 | if __name__ == '__main__': 49 | 50 | def check_it(func, matrix): 51 | result = func(matrix) 52 | if not all(-180 <= el <= 180 for el in result): 53 | print("The angles must be in range from -180 to 180 inclusively.") 54 | return False 55 | f, s, t = result 56 | temp = [0, 0, 0] 57 | temp[0] += f 58 | temp[1] += matrix[0][1] * f 59 | temp[2] += matrix[0][2] * f 60 | 61 | temp[0] += matrix[1][0] * s 62 | temp[1] += s 63 | temp[2] += matrix[1][2] * s 64 | 65 | temp[0] += matrix[2][0] * t 66 | temp[1] += matrix[2][1] * t 67 | temp[2] += t 68 | temp = [n % 360 for n in temp] 69 | if temp == [0, 225, 315]: 70 | return True 71 | else: 72 | print("This is the wrong final position {0}.".format(temp)) 73 | return False 74 | 75 | assert check_it(checkio, 76 | [[1, 2, 3], 77 | [3, 1, 2], 78 | [2, 3, 1]]), "1st example" 79 | assert check_it(checkio, 80 | [[1, 4, 2], 81 | [2, 1, 2], 82 | [2, 2, 1]]), "2nd example" 83 | assert check_it(checkio, 84 | [[1, 2, 5], 85 | [2, 1, 1], 86 | [2, 5, 1]]), "3rd example" -------------------------------------------------------------------------------- /bit-message.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | # encoding=utf8 3 | import datetime 4 | 5 | 6 | def checkio(data): 7 | #replace this for solution 8 | _type = int(data[1:2], 16) >> 2 9 | year = int(data[3] + data[2]) 10 | if year > 69: 11 | year += 1900 12 | else: 13 | year += 2000 14 | month = int(data[5] + data[4]) 15 | day = int(data[7] + data[6]) 16 | hour = int(data[9] + data[8]) 17 | minute = int(data[11] + data[10]) 18 | second = int(data[13] + data[12]) 19 | data15 = int(data[15], 16) 20 | sign = "+" 21 | if data15 / 8 == 1: 22 | sign = "-" 23 | timezone = int(str(data15 % 8) + data[14]) * 15 / 60 24 | if timezone == 0: 25 | sign = "+" 26 | DATEFORMAT = "%d %b %Y %H:%M:%S GMT %z" 27 | dt = datetime.datetime(year, month, day, hour, minute, second) 28 | p1 = dt.strftime(DATEFORMAT) + sign + str(timezone) 29 | length = int(data[16:18], 16) 30 | p2 = length 31 | offset = 18 32 | tmp = [] 33 | rest = data[offset:] 34 | for i in range((len(rest) + 1) / 2): 35 | tmp.append(rest[i * 2:i * 2 + 2]) 36 | tmp.reverse() 37 | rest = ''.join(tmp) 38 | clist = [] 39 | stream = bin(int(rest, 16))[2::] 40 | step = 16 41 | if _type == 0: 42 | step = 7 43 | elif _type == 1: 44 | step = 8 45 | stream = '0' * (length * step - len(stream)) + stream 46 | for i in range(length): 47 | s = stream[len(stream) - (i + 1) * step:len(stream) - i * step] 48 | if _type == 2: 49 | s = s[8:] + s[:8] 50 | clist.append(unichr(int(s, 2))) 51 | 52 | p3 = ''.join(clist) 53 | return [p1, p2, p3] 54 | 55 | 56 | #These "asserts" using only for self-checking and not necessary for auto-testing 57 | if __name__ == '__main__': 58 | assert (checkio(u'002080629173148007EDF27C1E3E9701') == 59 | ['26 Aug 2002 19:37:41 GMT +2', 7, u'message']), "First Test" 60 | 61 | assert (checkio(u'00317050201171820FD3323BDC0ED341C4303DEC3E8700') == 62 | ['05 Jul 2013 02:11:17 GMT +7', 15, u'Selamat Datang!']), "Second Test, 7 bit" 63 | 64 | assert (checkio(u'000130925161956915C8729E054A82C26D50DA0D7296EFA0EC5BBE06') == 65 | ['29 Mar 2010 15:16:59 GMT -4', 21, u'Hey, I am in New York']), "Third Test, negative timezone" 66 | 67 | assert (checkio( 68 | u'08071010101010611F04180441043A043B044E04470435043D043804350020043F043E04340442043204350440043604340430043504420020043F0440043004320438043B043E') == 69 | ['01 Jan 1970 01:01:01 GMT +4', 31, 70 | u'Исключение подтверждает правило']), "Fourth Test, simulate 32-bit signed integer real life problem" 71 | 72 | assert (checkio( 73 | u'088310913041804C23805E4E0D82E5805E4E4B002C805E4E4B4E0D82E5898B4E4B002C898B4E4B4E0D82E577E54E4B002C77E54E4B4E0D82E5884C4E4B002C5B7881F365BC884C4E4B800C6B6277E3 ') == 74 | ['19 Jan 2038 03:14:08 GMT -11', 35, u'聞不若聞之,聞之不若見之,見之不若知之,知之不若行之,學至於行之而止矣']), "But, we pass Y2K38 problem" 75 | -------------------------------------------------------------------------------- /web-log-sessions.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import time 3 | def formatURI(uri): 4 | domain = uri.split('/')[2] 5 | parts = domain.split('.') 6 | if len(parts) != 2: 7 | parts.pop(0) 8 | return '.'.join(parts).lower() 9 | 10 | 11 | class record: 12 | def __init__(self, string): 13 | parts = string.split(';;') 14 | self.t = time.mktime(time.strptime(parts[0], '%Y-%m-%d-%H-%M-%S')) 15 | self.u = parts[1].lower() 16 | self.d = formatURI(parts[2]) 17 | print 'new record: %s, %s, %s' % (self.t, self.u, self.d) 18 | 19 | def __cmp__(self, other): 20 | return self.t - other.t 21 | 22 | def __str__(self): 23 | return 'record: %s, %s, %s' % (self.t, self.u, self.d) 24 | 25 | 26 | class session: 27 | def __init__(self, rec): 28 | self.u = rec.u 29 | self.d = rec.d 30 | self.f = rec.t 31 | self.l = rec.t 32 | self.c = 1 33 | 34 | def isIn(self, rec): 35 | if rec.u == self.u and rec.d == self.d and rec.t < self.l+1800: 36 | return True 37 | return False 38 | 39 | def update(self, rec): 40 | self.l = rec.t 41 | self.c += 1 42 | 43 | def __str__(self): 44 | return "%s;;%s;;%d;;%d" % (self.u, self.d, int(self.l-self.f)+1, self.c) 45 | 46 | def __cmp__(self, other): 47 | if self.u != other.u: 48 | return cmp(self.u, other.u) 49 | if self.d != other.d: 50 | return cmp(self.d, other.d) 51 | d1 = int(self.l-self.f)+1 52 | d2 = int(other.l-other.f)+1 53 | if d1 != d2: 54 | return cmp(d1, d2) 55 | return cmp(self.c, other.c) 56 | 57 | 58 | class sessionController: 59 | def __init__(self): 60 | self.sl = [] 61 | print "session controller started." 62 | 63 | def insert(self, rec): 64 | for s in self.sl: 65 | if s.isIn(rec): 66 | s.update(rec) 67 | print "session updated" 68 | return 69 | self.sl.append(session(rec)) 70 | print "new session" 71 | 72 | def __str__(self): 73 | self.sl.sort() 74 | return '\n'.join([str(i) for i in self.sl]) 75 | 76 | 77 | def checkio(log_text): 78 | sc = sessionController() 79 | recordList = [] 80 | for line in log_text.split('\n'): 81 | recordList.append(record(line)) 82 | recordList.sort() 83 | for i in recordList: 84 | sc.insert(i) 85 | return str(sc) 86 | 87 | #These "asserts" using only for self-checking and not necessary for auto-testing 88 | if __name__ == '__main__': 89 | assert (checkio( 90 | """2013-01-01-01-00-00;;Name;;http://checkio.org/task 91 | 2013-01-01-01-02-00;;name;;http://checkio.org/task2 92 | 2013-01-01-01-31-00;;Name;;https://admin.checkio.org 93 | 2013-01-01-03-00-00;;Name;;http://www.checkio.org/profile 94 | 2013-01-01-03-00-01;;Name;;http://example.com 95 | 2013-02-03-04-00-00;;user2;;http://checkio.org/task 96 | 2013-01-01-03-11-00;;Name;;http://checkio.org/task""") 97 | == 98 | """name;;checkio.org;;661;;2 99 | name;;checkio.org;;1861;;3 100 | name;;example.com;;1;;1 101 | user2;;checkio.org;;1;;1"""), "Example" 102 | -------------------------------------------------------------------------------- /anagrams-by-stacks.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def getAction(state): 5 | ret = [] 6 | if len(state[0]) != 0: 7 | ret.append('01') 8 | ret.append('02') 9 | if len(state[1]) != 0: 10 | ret.append('12') 11 | if len(state[0]) == 0: 12 | ret.append('10') 13 | if len(state[2]) != 0: 14 | ret.append('21') 15 | if len(state[0]) == 0: 16 | ret.append('20') 17 | return ret 18 | 19 | 20 | def act(state, action): 21 | ret = [x[:] for x in state] 22 | src = int(action[0]) 23 | dest = int(action[1]) 24 | ret[dest].append(ret[src].pop()) 25 | return ret 26 | 27 | 28 | def hash(state): 29 | return '-'.join([''.join(x) for x in state]) 30 | 31 | 32 | def parse(string): 33 | return [x[::1] for x in string.split('-')] 34 | 35 | 36 | def checkio(data): 37 | start, end = data.split("-") 38 | opn = [] 39 | cls = [] 40 | state = dict() 41 | now = [[], list(start), []] 42 | state[hash(now)] = None 43 | while now != [[], [], list(end)]: 44 | cls.append(now) 45 | actions = getAction(now) 46 | for a in actions: 47 | nxt = act(now, a) 48 | if nxt in cls: 49 | continue 50 | if nxt in opn: 51 | continue 52 | if nxt not in opn: 53 | opn.append(nxt) 54 | state[hash(nxt)] = (hash(now), a) 55 | now = opn.pop(0) 56 | path = [] 57 | now = hash(now) 58 | while state[now]: 59 | s = state[now] 60 | path.append(s[1]) 61 | now = s[0] 62 | return ','.join(path[::-1]) 63 | 64 | 65 | if __name__ == '__main__': 66 | #This part is using only for self-checking and not necessary for auto-testing 67 | GOOD_ACTIONS = ("12", "10", "01", "02", "20", "21") 68 | 69 | def check_solution(func, anagrams, min_length): 70 | start, end = anagrams.split("-") 71 | stacks = [[], list(start), []] 72 | user_result = func(anagrams) 73 | actions = user_result.split(",") 74 | user_actions = [] 75 | for act in actions: 76 | if act not in GOOD_ACTIONS: 77 | print("Wrong action") 78 | return False 79 | from_s = int(act[0]) 80 | to_s = int(act[1]) 81 | if not stacks[from_s]: 82 | print("You can not get from an empty stack") 83 | return False 84 | if to_s == 0 and stacks[to_s]: 85 | print("You can not push in the full buffer") 86 | return False 87 | stacks[to_s].append(stacks[from_s].pop()) 88 | user_actions.append(act) 89 | res_word = ''.join(stacks[2]) 90 | if len(actions) > min_length: 91 | print("It can be shorter.") 92 | return False 93 | if res_word == end: 94 | return True 95 | else: 96 | print("The result anagram is wrong.") 97 | return False 98 | 99 | assert check_solution(checkio, u"rice-cire", 5), "rice-cire" 100 | assert check_solution(checkio, u"tort-trot", 4), "tort-trot" 101 | assert check_solution(checkio, u"hello-holle", 14), "hello-holle" 102 | assert check_solution(checkio, u"anagram-mragana", 8), "anagram-mragana" 103 | assert check_solution(checkio, u"mirror-mirorr", 25), "mirror-mirorr" 104 | -------------------------------------------------------------------------------- /scientific expedition/playfair-cipher.py: -------------------------------------------------------------------------------- 1 | import string 2 | m = "abcdefghijklmnopqrstuvwxyz0123456789" 3 | 4 | def getNewArray(key): 5 | newM = [] 6 | for c in key+m: 7 | if c not in newM: 8 | newM.append(c) 9 | return newM 10 | 11 | def getIndex(x, y): 12 | return 6 * x + y 13 | 14 | def getPosition(i): 15 | return i/6, i%6 16 | 17 | def encodeInner(m, first, second): 18 | x1, y1 = getPosition(m.index(first)) 19 | x2, y2 = getPosition(m.index(second)) 20 | if x1 == x2: 21 | first = m[getIndex(x1, (y1+1)%6)] 22 | second = m[getIndex(x2, (y2+1)%6)] 23 | elif y1 == y2: 24 | first = m[getIndex((x1+1)%6, y1)] 25 | second = m[getIndex((x2+1)%6, y2)] 26 | else: 27 | first = m[getIndex(x1, y2)] 28 | second = m[getIndex(x2, y1)] 29 | return first+second 30 | 31 | 32 | def encode(message, key): 33 | message = [string.lower(c) for c in message if c.isalnum()] 34 | newM = getNewArray(key) 35 | newMessage = [] 36 | i = 0 37 | while i!=len(message): 38 | if i+1 == len(message): 39 | if message[i] == 'z': 40 | newMessage.append(encodeInner(newM, 'z', 'x')) 41 | else: 42 | newMessage.append(encodeInner(newM, message[i], 'z')) 43 | i += 1 44 | elif message[i] == message[i+1]: 45 | if message[i] == 'x': 46 | newMessage.append(encodeInner(newM, 'x', 'z')) 47 | else: 48 | newMessage.append(encodeInner(newM, message[i], 'x')) 49 | i += 1 50 | else: 51 | newMessage.append(encodeInner(newM, message[i], message[i+1])) 52 | i += 2 53 | return ''.join(newMessage) 54 | 55 | 56 | def decodeInner(m, first, second): 57 | x1, y1 = getPosition(m.index(first)) 58 | x2, y2 = getPosition(m.index(second)) 59 | if x1 == x2: 60 | first = m[getIndex(x1, (y1-1)%6)] 61 | second = m[getIndex(x2, (y2-1)%6)] 62 | elif y1 == y2: 63 | first = m[getIndex((x1-1)%6, y1)] 64 | second = m[getIndex((x2-1)%6, y2)] 65 | else: 66 | first = m[getIndex(x1, y2)] 67 | second = m[getIndex(x2, y1)] 68 | return first+second 69 | 70 | 71 | def decode(secret_message, key): 72 | newM = getNewArray(key) 73 | newMessage = [] 74 | for i in range(0, len(secret_message), 2): 75 | newMessage.append(decodeInner(newM, secret_message[i], secret_message[i+1])) 76 | return ''.join(newMessage) 77 | 78 | 79 | if __name__ == '__main__': 80 | #These "asserts" using only for self-checking and not necessary for auto-testing 81 | assert encode("Fizz Buzz is x89 XX.", "checkio101") == 'do2y7mt22kry94y2y2', "Encode fizz buzz" 82 | assert decode("do2y7mt22kry94y2y2", "checkio101") == 'fizxzbuzzisx89xzxz', "Decode fizz buzz" 83 | assert encode("How are you?", "hello") == 'ea2imb1ht0', "Encode How are you" 84 | assert decode("ea2imb1ht0", "hello") == 'howareyouz', "Decode How are you" 85 | assert encode("My name is Alex!!!", "alexander") == 'i1dlkxjqlexn', "Encode Alex" 86 | assert decode("i1dlkxjqlexn", "alexander") == 'mynameisalex', "Decode Alex" 87 | assert encode("Who are you?", "human") == 'rnvftc1jd5', "Encode WHo" 88 | assert decode("rnvftc1jd5", "human") == 'whoareyouz', "Decode Who" 89 | assert encode("ATTACK AT DAWN", "general") == 'ewwektewhnua', "Encode attack" 90 | assert decode("ewwektewhnua", "general") == 'attackatdawn', "Decode attack" 91 | -------------------------------------------------------------------------------- /simplification.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | class polynomial: 5 | """class for polynomial""" 6 | 7 | 8 | def __init__(self, expr): 9 | if isinstance(expr, dict): 10 | self.dic = expr 11 | return 12 | 13 | self.dic = dict() 14 | if expr == 'x': 15 | self.dic[1] = 1 16 | else: 17 | self.dic[0] = int(expr) 18 | 19 | def __add__(self, other): 20 | # print "add", self, other 21 | ret = polynomial(self.dic.copy()) 22 | if isinstance(other, int): 23 | ret.dic.setdefault(0, 0) 24 | ret.dic[0] += other 25 | return ret 26 | 27 | for j in other.dic: 28 | ret.dic.setdefault(j, 0) 29 | ret.dic[j] += other.dic[j] 30 | return ret 31 | 32 | def __sub__(self, other): 33 | # print "sub", self, other 34 | ret = polynomial(self.dic.copy()) 35 | if isinstance(other, int): 36 | ret.dic.setdefault(0, 0) 37 | ret.dic[0] -= other 38 | return ret 39 | 40 | for j in other.dic: 41 | ret.dic.setdefault(j, 0) 42 | ret.dic[j] -= other.dic[j] 43 | return ret 44 | 45 | def __mul__(self, other): 46 | # print "mul", self, other 47 | ret = polynomial(self.dic.copy()) 48 | if isinstance(other, int): 49 | for i in ret.dic: 50 | ret.dic[i] *= other 51 | return ret 52 | 53 | ret = dict() 54 | for i in self.dic: 55 | for j in other.dic: 56 | ret.setdefault(i + j, 0) 57 | ret[i + j] += self.dic[i] * other.dic[j] 58 | return polynomial(ret) 59 | 60 | def __neg__(self): 61 | ret = polynomial(self.dic.copy()) 62 | for i in ret: 63 | ret[i] = -ret[i] 64 | return ret 65 | 66 | def __radd__(self, other): 67 | return self.__add__(other) 68 | 69 | def __rsub__(self, other): 70 | return -self.__add__(other) 71 | 72 | def __rmul__(self, other): 73 | # print "mul", self, other 74 | return self.__mul__(other) 75 | 76 | 77 | def __str__(self): 78 | ret = '' 79 | for k in self.dic.keys()[::-1]: 80 | C = self.dic[k] 81 | if C == 0: 82 | continue 83 | elif C == 1: 84 | if k == 0: 85 | ret += '+1' 86 | else: 87 | ret += '+x' + '*x' * (k - 1) 88 | elif C == -1: 89 | if k == 0: 90 | ret += '-1' 91 | else: 92 | ret += '-x' + '*x' * (k - 1) 93 | else: 94 | ret += '%+d' % C 95 | ret += '*x' * k 96 | return ret.strip('+') 97 | 98 | 99 | def checkio(expr): 100 | # expr = "x-x+"+expr 101 | ret = eval("x-x+" + expr, {'x': polynomial('x')}) 102 | return str(ret) 103 | 104 | #These "asserts" using only for self-checking and not necessary for auto-testing 105 | if __name__ == "__main__": 106 | assert checkio(u"(x-1)*(x+1)") == "x*x-1", "First and simple" 107 | assert checkio(u"(x+1)*(x+1)") == "x*x+2*x+1", "Almost the same" 108 | assert checkio(u"(x+3)*x*2-x*x") == "x*x+6*x", "Different operations" 109 | assert checkio(u"x+x*x+x*x*x") == "x*x*x+x*x+x", "Don't forget about order" 110 | assert checkio(u"(2*x+3)*2-x+x*x*x*x") == "x*x*x*x+3*x+6", "All together" -------------------------------------------------------------------------------- /matrix-pattern.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def isMatch(pattern, image, i, j): 5 | pHeight = len(pattern) 6 | pWidth = len(pattern[0]) 7 | for x in range(pHeight): 8 | for y in range(pWidth): 9 | if pattern[x][y] != image[i + x][j + y]: 10 | return False 11 | return True 12 | 13 | 14 | def add(pattern, image, i, j): 15 | pHeight = len(pattern) 16 | pWidth = len(pattern[0]) 17 | for x in range(pHeight): 18 | for y in range(pWidth): 19 | image[i + x][j + y] += 2 20 | 21 | 22 | def checkio(pattern, image): 23 | pHeight = len(pattern) 24 | pWidth = len(pattern[0]) 25 | iHeight = len(image) 26 | iWidth = len(image[0]) 27 | for i in range(iHeight - pHeight + 1): 28 | for j in range(iWidth - pWidth + 1): 29 | if isMatch(pattern, image, i, j): 30 | add(pattern, image, i, j) 31 | return image 32 | 33 | #These "asserts" using only for self-checking and not necessary for auto-testing 34 | if __name__ == '__main__': 35 | checkio([[0, 0, 0], [0, 0, 0], [0, 0, 0]], 36 | [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0], 37 | [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], 38 | [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0], 39 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0], 40 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], 41 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]]) 42 | assert checkio([[1, 0], [1, 1]], 43 | [[0, 1, 0, 1, 0], 44 | [0, 1, 1, 0, 0], 45 | [1, 0, 1, 1, 0], 46 | [1, 1, 0, 1, 1], 47 | [0, 1, 1, 0, 0]]) == [[0, 3, 2, 1, 0], 48 | [0, 3, 3, 0, 0], 49 | [3, 2, 1, 3, 2], 50 | [3, 3, 0, 3, 3], 51 | [0, 1, 1, 0, 0]] 52 | assert checkio([[1, 1], [1, 1]], 53 | [[1, 1, 1], 54 | [1, 1, 1], 55 | [1, 1, 1]]) == [[3, 3, 1], 56 | [3, 3, 1], 57 | [1, 1, 1]] 58 | assert checkio([[0, 1, 0], [1, 1, 1]], 59 | [[0, 0, 1, 0, 0, 0, 0, 0, 1, 0], 60 | [0, 1, 1, 1, 0, 0, 0, 1, 1, 1], 61 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 62 | [0, 0, 0, 0, 0, 1, 0, 0, 0, 0], 63 | [0, 1, 0, 0, 1, 1, 1, 0, 1, 0], 64 | [1, 1, 1, 0, 0, 0, 0, 0, 1, 1], 65 | [0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 66 | [0, 0, 1, 0, 0, 0, 0, 1, 0, 0], 67 | [0, 1, 1, 0, 0, 0, 1, 1, 1, 0], 68 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) == [[0, 2, 3, 2, 0, 0, 0, 2, 3, 2], 69 | [0, 3, 3, 3, 0, 0, 0, 3, 3, 3], 70 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 71 | [0, 0, 0, 0, 2, 3, 2, 0, 0, 0], 72 | [2, 3, 2, 0, 3, 3, 3, 0, 1, 0], 73 | [3, 3, 3, 0, 0, 0, 0, 0, 1, 1], 74 | [0, 0, 0, 1, 1, 1, 0, 0, 0, 0], 75 | [0, 0, 1, 0, 0, 0, 2, 3, 2, 0], 76 | [0, 1, 1, 0, 0, 0, 3, 3, 3, 0], 77 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 78 | 79 | -------------------------------------------------------------------------------- /8-puzzle.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | MOVES = {'U': (-1, 0), 'D': (1, 0), 'L': (0, -1), 'R': (0, 1)} 4 | 5 | def deepcopy(puzzle): 6 | return [x[:] for x in puzzle] 7 | 8 | def puzzle2int(puzzle): 9 | ret = '' 10 | for i in range(3): 11 | for j in range(3): 12 | ret += str(puzzle[i][j]) 13 | return int(ret) 14 | 15 | 16 | class state(): 17 | def __init__(self, puzzle, g, pre): 18 | self.puzzle = puzzle 19 | self.h = self._h_() 20 | self.g = g 21 | self.pre = pre 22 | 23 | def __hash__(self): 24 | return puzzle2int(self.puzzle) 25 | 26 | 27 | def _h_(self): 28 | h = 0 29 | for x, row in enumerate(self.puzzle): 30 | for y, value in enumerate(row): 31 | if value != 0: 32 | destx = (value - 1) / 3 33 | desty = (value - 1) % 3 34 | h += abs(x - destx) + abs(y - desty) 35 | return h 36 | 37 | def __str__(self): 38 | ret = '' 39 | for i in range(3): 40 | for j in range(3): 41 | ret += str(self.puzzle[i][j]) 42 | return ret 43 | 44 | def isComplete(self): 45 | return self.h == 0 46 | 47 | def getBlank(self): 48 | for i in range(3): 49 | for j in range(3): 50 | if self.puzzle[i][j] == 0: 51 | return i, j 52 | 53 | def nextMove(self): 54 | ret = [] 55 | i, j = self.getBlank() 56 | for m in MOVES: 57 | newi = i + MOVES[m][0] 58 | newj = j + MOVES[m][1] 59 | if 0 <= newi < 3 and 0 <= newj < 3: 60 | newPuzzle = deepcopy(self.puzzle) 61 | newPuzzle[newi][newj], newPuzzle[i][j] = newPuzzle[i][j], newPuzzle[newi][newj] 62 | ret.append(newPuzzle) 63 | return ret 64 | 65 | def f(self): 66 | return self.g + self.h 67 | 68 | 69 | def checkio(puzzle): 70 | now = state(deepcopy(puzzle), 0, None) 71 | opened = {} 72 | closed = {} 73 | opened[hash(now)] = now 74 | while not now.isComplete(): 75 | opened.pop(hash(now)) 76 | closed[hash(now)] = now 77 | nxt = now.nextMove() 78 | for n in nxt: 79 | if puzzle2int(n) in closed.keys(): 80 | continue 81 | if puzzle2int(n) not in opened.keys(): 82 | newState = state(n, now.g + 1, now) 83 | opened[hash(newState)] = newState 84 | else: 85 | if opened[puzzle2int(n)].f() > now.f() + 1: 86 | opened[puzzle2int(n)].g = now.g + 1 87 | opened[puzzle2int(n)].pre = now 88 | now = min(opened.items(), key=lambda x: x[1].f())[1] 89 | route = '' 90 | while now.pre: 91 | nxt = now 92 | now = now.pre 93 | x1, y1 = now.getBlank() 94 | x2, y2 = nxt.getBlank() 95 | dx, dy = x2 - x1, y2 - y1 96 | for m in MOVES: 97 | if MOVES[m] == (dx, dy): 98 | route += m 99 | return route[::-1] 100 | 101 | 102 | if __name__ == '__main__': 103 | #This part is using only for self-checking and not necessary for auto-testing 104 | GOAL = [[1, 2, 3], [4, 5, 6], [7, 8, 0]] 105 | 106 | MOVES = {'U': (-1, 0), 'D': (1, 0), 'L': (0, -1), 'R': (0, 1)} 107 | 108 | def check_solution(func, puzzle): 109 | size = len(puzzle) 110 | route = func([row[:] for row in puzzle]) 111 | goal = GOAL 112 | x = y = None 113 | for i, row in enumerate(puzzle): 114 | if 0 in row: 115 | x, y = i, row.index(0) 116 | break 117 | for ch in route: 118 | swap_x, swap_y = x + MOVES[ch][0], y + MOVES[ch][1] 119 | if 0 <= swap_x < size and 0 <= swap_y < size: 120 | puzzle[x][y], puzzle[swap_x][swap_y] = puzzle[swap_x][swap_y], 0 121 | x, y = swap_x, swap_y 122 | if puzzle == goal: 123 | return True 124 | else: 125 | print("Puzzle is not solved") 126 | return False 127 | 128 | assert check_solution(checkio, [[1, 2, 3], 129 | [4, 6, 8], 130 | [7, 5, 0]]), "1st example" 131 | assert check_solution(checkio, [[7, 3, 5], 132 | [4, 8, 6], 133 | [1, 2, 0]]), "2nd example" 134 | assert check_solution(checkio, [[2, 4, 5], [1, 7, 3], [8, 6, 0]]), "2nd example" 135 | 136 | -------------------------------------------------------------------------------- /pycon tw 2014/behind-2048.py: -------------------------------------------------------------------------------- 1 | win = [['U','W','I','N']]*4 2 | lose = [['G','A','M','E'],['O','V','E','R']]*2 3 | 4 | 5 | def rotateRight(state): 6 | return [list(line) for line in zip(*state[::-1])] 7 | 8 | 9 | def pullLeft(state): 10 | for i in xrange(0, 4): 11 | for j in xrange(0, 3): 12 | if state[i][j] != 0: 13 | for k in range(j+1, 4): 14 | if state[i][k] != 0: 15 | break 16 | if state[i][k] == state[i][j]: 17 | state[i][j] *= 2 18 | state[i][k] = 0 19 | for j in xrange(0, 3): 20 | if state[i][j] == 0: 21 | for k in range(j+1, 4): 22 | if state[i][k] != 0: 23 | break 24 | state[i][j] = state[i][k] 25 | state[i][k] = 0 26 | return state 27 | 28 | 29 | def check(state): 30 | moved = False 31 | for i in xrange(3,-1,-1): 32 | for j in xrange(3,-1,-1): 33 | if not moved and state[i][j] == 0: 34 | state[i][j] = 2 35 | moved = True 36 | if state[i][j] == 2048: 37 | return win 38 | if not moved: 39 | return lose 40 | return state 41 | 42 | def move2048(state, move): 43 | if move == 'up': 44 | state = rotateRight(state) 45 | state = rotateRight(state) 46 | state = rotateRight(state) 47 | state = pullLeft(state) 48 | state = rotateRight(state) 49 | elif move == 'down': 50 | state = rotateRight(state) 51 | state = pullLeft(state) 52 | state = rotateRight(state) 53 | state = rotateRight(state) 54 | state = rotateRight(state) 55 | elif move == 'left': 56 | state = pullLeft(state) 57 | elif move == 'right': 58 | state = rotateRight(state) 59 | state = rotateRight(state) 60 | state = pullLeft(state) 61 | state = rotateRight(state) 62 | state = rotateRight(state) 63 | else: 64 | pass 65 | state = check(state) 66 | return state 67 | 68 | 69 | if __name__ == '__main__': 70 | # These "asserts" using only for self-checking and not necessary for auto-testing 71 | assert move2048([[0, 2, 0, 0], 72 | [0, 0, 0, 0], 73 | [0, 0, 0, 0], 74 | [0, 2, 0, 0]], 'up') == [[0, 4, 0, 0], 75 | [0, 0, 0, 0], 76 | [0, 0, 0, 0], 77 | [0, 0, 0, 2]], "Start. Move Up!" 78 | assert move2048([[4, 0, 0, 0], 79 | [0, 4, 0, 0], 80 | [0, 0, 0, 0], 81 | [0, 0, 8, 8]], 'right') == [[0, 0, 0, 4], 82 | [0, 0, 0, 4], 83 | [0, 0, 0, 0], 84 | [0, 0, 2, 16]], "Simple right" 85 | assert move2048([[2, 0, 2, 2], 86 | [0, 4, 4, 4], 87 | [8, 8, 8, 16], 88 | [0, 0, 0, 0]], 'right') == [[0, 0, 2, 4], 89 | [0, 0, 4, 8], 90 | [0, 8, 16, 16], 91 | [0, 0, 0, 2]], "Three merging" 92 | assert move2048([[256, 0, 256, 4], 93 | [16, 8, 8, 0], 94 | [32, 32, 32, 32], 95 | [4, 4, 2, 2]], 'right') == [[0, 0, 512, 4], 96 | [0, 0, 16, 16], 97 | [0, 0, 64, 64], 98 | [0, 2, 8, 4]], "All right" 99 | assert move2048([[4, 4, 0, 0], 100 | [0, 4, 1024, 0], 101 | [0, 256, 0, 256], 102 | [0, 1024, 1024, 8]], 'down') == [['U', 'W', 'I', 'N'], 103 | ['U', 'W', 'I', 'N'], 104 | ['U', 'W', 'I', 'N'], 105 | ['U', 'W', 'I', 'N']], "We are the champions!" 106 | assert move2048([[2, 4, 8, 16], 107 | [32, 64, 128, 256], 108 | [512, 1024, 2, 4], 109 | [8, 16, 32, 64]], 'left') == [['G', 'A', 'M', 'E'], 110 | ['O', 'V', 'E', 'R'], 111 | ['G', 'A', 'M', 'E'], 112 | ['O', 'V', 'E', 'R']], "Nobody moves!" 113 | -------------------------------------------------------------------------------- /electronic station/parse-array.py: -------------------------------------------------------------------------------- 1 | WHITESPACE_STR = ' \t\n\r' 2 | 3 | 4 | def parse_array(s, _w=WHITESPACE_STR, _sep=","): 5 | array = None 6 | stack = [] 7 | accumulator = "" 8 | closed_flag = False 9 | sep_flag = False 10 | whitespace_flag = False 11 | started_flag = False 12 | for ch in s: 13 | if ch in _w: 14 | whitespace_flag = True 15 | continue 16 | if ch == "[": 17 | if started_flag and not stack: 18 | raise ValueError("Wrong string.") 19 | if closed_flag or accumulator: 20 | raise ValueError 21 | in_array = [] 22 | if stack: 23 | stack[-1](in_array) 24 | else: 25 | array = in_array 26 | started_flag = True 27 | stack.append(in_array.append) 28 | elif not started_flag: 29 | raise ValueError("Wrong string.") 30 | elif ch == "]": 31 | 32 | if not stack: 33 | raise ValueError("Wrong string.") 34 | if accumulator: 35 | stack[-1](int(accumulator)) 36 | accumulator = "" 37 | stack.pop() 38 | closed_flag = True 39 | sep_flag = False 40 | whitespace_flag = False 41 | elif ch in _sep: 42 | if accumulator: 43 | stack[-1](int(accumulator)) 44 | accumulator = "" 45 | elif not stack: 46 | raise ValueError("Wrong string.") 47 | elif closed_flag: 48 | pass 49 | else: 50 | raise ValueError("Wrong string.") 51 | sep_flag = True 52 | closed_flag = False 53 | whitespace_flag = False 54 | else: 55 | if whitespace_flag and accumulator or closed_flag: 56 | raise ValueError 57 | accumulator += ch 58 | whitespace_flag = False 59 | if stack: 60 | raise ValueError("Wrong string") 61 | if not array is None: 62 | return array 63 | else: 64 | raise ValueError("Wrong string") 65 | 66 | 67 | if __name__ == "__main__": 68 | #These "asserts" using only for self-checking and not necessary for auto-testing 69 | assert parse_array("[1, 2, 3]") == [1, 2, 3], "Simple" 70 | assert parse_array("[[1], 2, 3]") == [[1], 2, 3], "Nested" 71 | assert parse_array("[-3, [-2, 0], 10]") == [-3, [-2, 0], 10], "Negative integers" 72 | assert parse_array("[100]") == [100], "One number" 73 | assert parse_array("[2, 3]") == [2, 3], "Whitespaces" 74 | assert parse_array("[[10, [11]], [[[1], 2], 3], 5]") == [[10, [11]], [[[1], 2], 3], 5], "Deep nested" 75 | assert parse_array(" [3, 4] ") == [3, 4], "Skip whitespaces" 76 | assert parse_array("[[], 0]") == [[], 0], "Empty arrays" 77 | assert parse_array("[[0,], 0]") == [[0], 0], "Comma - closed bracket" 78 | 79 | try: 80 | parse_array("[asd]") 81 | assert False, "Only integers" 82 | except ValueError: 83 | pass 84 | 85 | try: 86 | parse_array("[2, 3]]") 87 | assert False, "Excess bracket" 88 | except ValueError: 89 | pass 90 | 91 | try: 92 | parse_array("[++2, 1]") 93 | assert False, "Two plus" 94 | except ValueError: 95 | pass 96 | 97 | try: 98 | parse_array("[10, 11, , 12]") 99 | assert False, "Two separators" 100 | except ValueError: 101 | pass 102 | 103 | try: 104 | parse_array(" 13 ") 105 | assert False, "Where is a list?" 106 | except ValueError: 107 | pass 108 | 109 | try: 110 | parse_array("[[2]") 111 | assert False, "Excess opened bracket" 112 | except ValueError: 113 | pass 114 | 115 | try: 116 | parse_array("[3 4]") 117 | assert False, "Check for spurious spaces within a number" 118 | except ValueError: 119 | pass 120 | 121 | try: 122 | parse_array("[10, 11,, 12]") 123 | assert False, "Check for double separators without a space in between" 124 | except ValueError: 125 | pass 126 | 127 | try: 128 | parse_array("[[]3]") 129 | assert False, "Check for missing separators after []" 130 | except ValueError: 131 | pass 132 | 133 | try: 134 | parse_array("[2[]]") 135 | assert False, " Check for missing separators before []" 136 | except ValueError: 137 | pass 138 | 139 | try: 140 | parse_array("[3],") 141 | assert False, "Excess separator" 142 | except ValueError: 143 | pass 144 | 145 | try: 146 | parse_array("[1,2]3") 147 | assert False, "Excess number" 148 | except ValueError: 149 | pass 150 | 151 | try: 152 | parse_array("[1], [2,3]") 153 | assert False, "Here should be only one array." 154 | except ValueError: 155 | pass 156 | -------------------------------------------------------------------------------- /minesweeper.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | def unopenedAround(field, row, col): 5 | offsetPair = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)] 6 | count = 0 7 | for i in offsetPair: 8 | if row + i[0] in range(10) and col + i[1] in range(10) and field[row + i[0]][col + i[1]] == -1: 9 | count += 1 10 | return count 11 | 12 | 13 | def mineAround(field, row, col): 14 | offsetPair = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)] 15 | count = 0 16 | for i in offsetPair: 17 | if row + i[0] in range(10) and col + i[1] in range(10) and field[row + i[0]][col + i[1]] == 9: 18 | count += 1 19 | return count 20 | 21 | 22 | def openCell(field, row, col): 23 | offsetPair = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)] 24 | for i in offsetPair: 25 | if row + i[0] in range(10) and col + i[1] in range(10) and field[row + i[0]][col + i[1]] == -1: 26 | return row + i[0], col + i[1] 27 | return 0, 0 28 | 29 | 30 | def checkio(field): 31 | for i in range(10): 32 | for j in range(10): 33 | if field[i][j] != 0 and field[i][j] != 9 and unopenedAround(field, i, j) != 0: 34 | if field[i][j] - mineAround(field, i, j) == unopenedAround(field, i, j): 35 | row, col = openCell(field, i, j) 36 | return [True, row, col] 37 | if field[i][j] - mineAround(field, i, j) == 0: 38 | row, col = openCell(field, i, j) 39 | return [False, row, col] 40 | return [False, 0, 0] 41 | 42 | #This part is using only for self-testing 43 | if __name__ == '__main__': 44 | 45 | def check_is_win_referee(input_map): 46 | unopened = [1 for x in range(10) for y in range(10) if input_map[x][y] == -1] 47 | return not unopened 48 | 49 | def build_map(input_map, mine_map, row, col): 50 | opened = [(row, col)] 51 | while opened: 52 | i, j = opened.pop(0) 53 | neighs = [(i + x, j + y) for x, y in [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] 54 | if 0 <= i + x < 10 and 0 <= j + y < 10] 55 | value = sum([mine_map[k][l] for k, l in neighs]) 56 | input_map[i][j] = value 57 | if not value: 58 | for k, l in neighs: 59 | if input_map[k][l] == -1 and (k, l) not in opened: 60 | opened.append((k, l)) 61 | return input_map 62 | 63 | def check_solution(func, mine_map): 64 | input_map = [[-1] * 10 for _ in range(10)] 65 | while True: 66 | 67 | is_mine, row, col = func([row[:] for row in input_map]) # using copy 68 | if input_map[row][col] != -1: 69 | print("You tried to uncover or mark already opened cell.") 70 | return False 71 | if is_mine and not mine_map[row][col]: 72 | print("You marked the wrong cell.") 73 | return False 74 | if not is_mine and mine_map[row][col]: 75 | print("You uncovered a mine. BANG!") 76 | return False 77 | if is_mine: 78 | input_map[row][col] = 9 79 | else: 80 | build_map(input_map, mine_map, row, col) 81 | if check_is_win_referee(input_map): 82 | return True 83 | return False 84 | 85 | assert check_solution(checkio, [ 86 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 87 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 88 | [0, 0, 1, 0, 1, 0, 0, 1, 0, 0], 89 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 90 | [0, 0, 1, 0, 1, 0, 0, 0, 0, 0], 91 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 92 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 93 | [0, 0, 1, 0, 1, 0, 0, 1, 0, 0], 94 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 95 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), "Simple" 96 | 97 | assert check_solution(checkio, [ 98 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 99 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 100 | [0, 1, 1, 0, 0, 0, 1, 1, 1, 0], 101 | [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], 102 | [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], 103 | [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], 104 | [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], 105 | [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], 106 | [0, 1, 1, 1, 1, 1, 1, 1, 1, 0], 107 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), "Gate" 108 | 109 | assert check_solution(checkio, [ 110 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 111 | [0, 0, 0, 0, 0, 0, 0, 0, 1, 0], 112 | [0, 0, 1, 1, 0, 0, 1, 0, 0, 0], 113 | [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], 114 | [0, 0, 1, 0, 0, 0, 0, 1, 0, 0], 115 | [0, 0, 0, 0, 0, 1, 0, 0, 0, 0], 116 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 117 | [0, 0, 0, 0, 1, 0, 0, 0, 1, 0], 118 | [0, 0, 1, 0, 0, 0, 1, 0, 0, 0], 119 | [0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]), "Various" 120 | 121 | 122 | -------------------------------------------------------------------------------- /bats-bunker.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | from fractions import Fraction 4 | 5 | 6 | def canPass(x1, x2, y1, y2, bunker): 7 | dx = x1 - x2 8 | dy = y1 - y2 9 | 10 | if dx == 0: 11 | if y1 > y2: 12 | y1, y2 = y2, y1 13 | for c in bunker[x1][y1:y2 + 1]: 14 | if c == 'W': 15 | return False 16 | return True 17 | 18 | if dy == 0: 19 | if x1 > x2: 20 | x1, x2 = x2, x1 21 | for c in bunker[x1:x2 + 1]: 22 | if c[y1] == 'W': 23 | return False 24 | return True 25 | 26 | if abs(dx) >= abs(dy): 27 | k = Fraction(dy, dx) 28 | if dx > 0: 29 | x1, y1, x2, y2 = x2, y2, x1, y1 30 | start = y1 + k/2 31 | for i in range(abs(dx)): 32 | nowy = start + i * k 33 | nowx = x1 + i 34 | if bunker[nowx][int(nowy+.5)] == 'W' or bunker[nowx+1][int(nowy+.5)] == 'W': 35 | return False 36 | if int(nowy+.5) == nowy+.5: 37 | if bunker[nowx][int(nowy+.5)-1] == 'W' or bunker[nowx+1][int(nowy+.5)-1] == 'W': 38 | return False 39 | return True 40 | 41 | if abs(dx) < abs(dy): 42 | k = Fraction(dx, dy) 43 | if dy > 0: 44 | x1, y1, x2, y2 = x2, y2, x1, y1 45 | start = x1 + k/2 46 | for i in range(abs(dy)): 47 | nowx = start + i * k 48 | nowy = y1 + i 49 | if bunker[int(nowx+.5)][nowy] == 'W' or bunker[int(nowx+.5)][nowy+1] == 'W': 50 | return False 51 | if int(nowx+.5) == nowx+.5: 52 | if bunker[int(nowx+.5)-1][nowy] == 'W' or bunker[int(nowx+.5)-1][nowy+1] == 'W': 53 | return False 54 | return True 55 | 56 | return True 57 | 58 | 59 | def distance(x, y): 60 | x1, y1 = x 61 | x2, y2 = y 62 | return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** .5 63 | 64 | 65 | def checkio(bunker): 66 | width = len(bunker) 67 | length = len(bunker[0]) 68 | bats = [] 69 | dest = (0, 0) 70 | neighbor = {} 71 | for i in range(width): 72 | for j in range(length): 73 | if bunker[i][j] == 'B': 74 | bats.append((i, j)) 75 | if bunker[i][j] == 'A': 76 | bats.append((i, j)) 77 | dest = (i, j) 78 | batsNum = len(bats) 79 | for i in range(batsNum - 1): 80 | for j in range(i + 1, batsNum): 81 | x1, y1 = bats[i] 82 | x2, y2 = bats[j] 83 | if canPass(x1, x2, y1, y2, bunker): 84 | neighbor.setdefault(bats[i], []).append(bats[j]) 85 | neighbor.setdefault(bats[j], []).append(bats[i]) 86 | active = (0, 0) 87 | open = [active] 88 | closed = [] 89 | status = dict() 90 | status[active] = (0, distance(active, dest), None) 91 | while active != dest: 92 | open.remove(active) 93 | closed.append(active) 94 | nxt = neighbor[active] 95 | for n in nxt: 96 | if n in closed: 97 | continue 98 | if n not in open: 99 | open.append(n) 100 | status[n] = [status[active][0] + distance(n, active), distance(n, dest), active] 101 | else: 102 | disg = status[active][0] + distance(n, active) 103 | if status[n][0] > disg: 104 | status[n][0] = disg 105 | status[n][2] = active 106 | f = 10000 107 | for i in open: 108 | if status[i][0] + status[i][1] < f: 109 | f = status[i][0] + status[i][1] 110 | active = i 111 | now = active 112 | while status[now][2]: 113 | now = status[now][2] 114 | 115 | return status[active][0] + status[active][1] 116 | 117 | #These "asserts" using only for self-checking and not necessary for auto-testing 118 | if __name__ == '__main__': 119 | def almost_equal(checked, correct, significant_digits=2): 120 | precision = 0.1 ** significant_digits 121 | return correct - precision < checked < correct + precision 122 | 123 | assert almost_equal(checkio([ 124 | "B--", 125 | "---", 126 | "--A"]), 2.83), "1st example" 127 | assert almost_equal(checkio([ 128 | "B-B", 129 | "BW-", 130 | "-BA"]), 4), "2nd example" 131 | assert almost_equal(checkio([ 132 | "BWB--B", 133 | "-W-WW-", 134 | "B-BWAB"]), 12), "3rd example" 135 | assert almost_equal(checkio([ 136 | "B---B-", 137 | "-WWW-B", 138 | "-WA--B", 139 | "-W-B--", 140 | "-WWW-B", 141 | "B-BWB-"]), 9.24), "4th example" 142 | 143 | assert almost_equal(checkio(["B-B-B", "-WWW-", "BWA-B", "-WWW-", "B-B-B"]), 8), "5th example" 144 | assert almost_equal(checkio(["BWA-B-", "-W----", "-WW-B-", "-W---B", "--B---", "B-B---"]), 12.83), "6th example" 145 | checkio(["BBBBB","BBBBB","BBBBB","BBBBB","BBBBA"]) 146 | 147 | -------------------------------------------------------------------------------- /express-delivery.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | import itertools 3 | from operator import add 4 | 5 | 6 | def disMap(s, field_map): 7 | opn = [s] 8 | closed = [] 9 | nodes = list(itertools.product(range(len(field_map)), range(len(field_map[0])))) 10 | dis = dict() 11 | dis[s] = 0 12 | while opn: 13 | now = opn.pop(0) 14 | closed.append(now) 15 | for d in [(-1, 0), (1, 0), (0, -1), (0, 1)]: 16 | neighbor = tuple(map(add, now, d)) 17 | if neighbor in nodes and field_map[neighbor[0]][neighbor[1]] != 'W': 18 | if neighbor in closed: 19 | continue 20 | if neighbor in opn: 21 | continue 22 | opn.append(neighbor) 23 | dis[neighbor] = dis[now] + 1 24 | return dis 25 | 26 | 27 | def findPath(s, e, field_map): 28 | opn = [] 29 | closed = [s] 30 | nodes = list(itertools.product(range(len(field_map)), range(len(field_map[0])))) 31 | father = dict() 32 | father[s] = None 33 | now = s 34 | while now != e: 35 | closed.append(now) 36 | for d in [(-1, 0), (1, 0), (0, -1), (0, 1)]: 37 | neighbor = tuple(map(add, now, d)) 38 | if neighbor in nodes and field_map[neighbor[0]][neighbor[1]] != 'W': 39 | if neighbor in closed: 40 | continue 41 | if neighbor in opn: 42 | continue 43 | opn.append(neighbor) 44 | father[neighbor] = now 45 | now = opn.pop(0) 46 | ACTIONS = { 47 | (0, -1): "L", 48 | (0, 1): "R", 49 | (-1, 0): "U", 50 | (1, 0): "D" 51 | } 52 | 53 | path = [] 54 | while father[now]: 55 | pre = father[now] 56 | path.append(ACTIONS[(now[0]-pre[0], now[1]-pre[1])]) 57 | now = pre 58 | return ''.join(path[::-1]) 59 | 60 | 61 | def checkio(field_map): 62 | boxList = [] 63 | for i in range(len(field_map)): 64 | for j in range(len(field_map[0])): 65 | if field_map[i][j] == 'S': 66 | s = (i, j) 67 | if field_map[i][j] == 'E': 68 | e = (i, j) 69 | if field_map[i][j] == 'B': 70 | boxList.append((i, j)) 71 | 72 | disFromStart = disMap(s, field_map) 73 | disFromEnd = disMap(e, field_map) 74 | 75 | minTime = 2 * disFromStart[e] 76 | boxes = None 77 | 78 | for b1, b2 in [(x, y) for x in boxList for y in boxList]: 79 | dis = 2 + 2 * disFromStart[b1] 80 | dis += 2 * disFromEnd[b2] 81 | dis += disMap(b1, field_map)[b2] 82 | if dis < minTime: 83 | minTime = dis 84 | boxes = [b1, b2] 85 | 86 | if boxes: 87 | return findPath(s, boxes[0], field_map)+'B'+findPath(boxes[0], boxes[1], field_map)+'B'+findPath(boxes[1], e, field_map) 88 | else: 89 | return findPath(s, e, field_map) 90 | 91 | 92 | if __name__ == '__main__': 93 | #This part is using only for self-checking and not necessary for auto-testing 94 | ACTIONS = { 95 | "L": (0, -1), 96 | "R": (0, 1), 97 | "U": (-1, 0), 98 | "D": (1, 0), 99 | "B": (0, 0) 100 | } 101 | 102 | def check_solution(func, max_time, field): 103 | max_row, max_col = len(field), len(field[0]) 104 | s_row, s_col = 0, 0 105 | total_time = 0 106 | hold_box = True 107 | route = func(field[:]) 108 | for step in route: 109 | if step not in ACTIONS: 110 | print("Unknown action {0}".format(step)) 111 | return False 112 | if step == "B": 113 | if hold_box: 114 | if field[s_row][s_col] == "B": 115 | hold_box = False 116 | total_time += 1 117 | continue 118 | else: 119 | print("Stephan broke the cargo") 120 | return False 121 | else: 122 | if field[s_row][s_col] == "B": 123 | hold_box = True 124 | total_time += 1 125 | continue 126 | n_row, n_col = s_row + ACTIONS[step][0], s_col + ACTIONS[step][1], 127 | total_time += 2 if hold_box else 1 128 | if 0 > n_row or n_row >= max_row or 0 > n_col or n_row >= max_col: 129 | print("We've lost Stephan.") 130 | return False 131 | if field[n_row][n_col] == "W": 132 | print("Stephan fell in water.") 133 | return False 134 | s_row, s_col = n_row, n_col 135 | if field[s_row][s_col] == "E" and hold_box: 136 | if total_time <= max_time: 137 | return True 138 | else: 139 | print("You can deliver the cargo faster.") 140 | return False 141 | print("The cargo is not delivered") 142 | return False 143 | 144 | assert check_solution(checkio, 12, ["S...", "....", "B.WB", "..WE"]), "1st Example" 145 | assert check_solution(checkio, 11, ["S...", "....", "B..B", "..WE"]), "2nd example" -------------------------------------------------------------------------------- /magic-square.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | # import itertools 3 | # 4 | # 5 | # def test(data): 6 | # n = len(data) 7 | # magic_constant = n * (n ** 2 + 1) / 2 8 | # for i in range(n): 9 | # if sum(data[i]) != magic_constant: 10 | # return False 11 | # trans = zip(*data) 12 | # for i in range(n): 13 | # if sum(trans[i]) != magic_constant: 14 | # return False 15 | # if sum([data[i][i] for i in range(n)]) != magic_constant: 16 | # return False 17 | # if sum([data[i][n-1-i] for i in range(n)]) != magic_constant: 18 | # return False 19 | # return True 20 | # 21 | # 22 | # def checkio(data): 23 | # n = len(data) 24 | # data2 = [[x for x in y] for y in data] 25 | # candidates = range(1, n ** 2 + 1) 26 | # for x in data: 27 | # for y in x: 28 | # if y != 0: 29 | # candidates.remove(y) 30 | # for p in itertools.permutations(candidates): 31 | # k = 0 32 | # for x in range(n): 33 | # for y in range(n): 34 | # if data[x][y] == 0: 35 | # data2[x][y] = p[k] 36 | # k += 1 37 | # if test(data2): 38 | # return data2 39 | # return [[0, 0, 0], [0, 0, 0], [0, 0, 0]] 40 | 41 | def is_valid(data): 42 | n = len(data) 43 | rows = [sum(row) for row in data] 44 | cols = [sum(col) for col in zip(*data)] 45 | diag = [ 46 | sum(data[i][i] for i in range(n)), 47 | sum(data[i][n-i-1] for i in range(n)), 48 | ] 49 | return set(rows + cols + diag) == set([n * (n * n + 1) / 2]) 50 | 51 | def should_continue(data): 52 | n = len(data) 53 | M = n * (n * n + 1) / 2 54 | return all(sum(row) <= M for row in data) and \ 55 | all(sum(col) <= M for col in zip(*data)) and \ 56 | sum(data[i][i] for i in range(n)) <= M and \ 57 | sum(data[i][n-i-1] for i in range(n)) <= M 58 | 59 | def get_candidate(data): 60 | n = len(data) 61 | ni, nj = None, None 62 | for i in range(n): 63 | for j in range(n): 64 | if data[i][j] == 0: 65 | ni, nj = i, j 66 | break 67 | if ni is not None: break 68 | return [(ni, nj, x) for x in set(range(1, n * n + 1)) - set(sum(data, [])) - set([0])] 69 | 70 | def backtrack(data): 71 | if not should_continue(data): 72 | return None 73 | if is_valid(data): 74 | return data 75 | candidate = get_candidate(data) 76 | for i, j, c in candidate: 77 | data[i][j] = c 78 | r = backtrack(data) 79 | if r is not None: 80 | return r 81 | data[i][j] = 0 82 | 83 | def checkio(data): 84 | return backtrack(data) 85 | 86 | 87 | if __name__ == '__main__': 88 | #This part is using only for self-testing. 89 | def check_solution(func, in_square): 90 | SIZE_ERROR = "Wrong size of the answer." 91 | MS_ERROR = "It's not a magic square." 92 | NORMAL_MS_ERROR = "It's not a normal magic square." 93 | NOT_BASED_ERROR = "Hm, this square is not based on given template." 94 | result = func(in_square) 95 | #check sizes 96 | N = len(result) 97 | if len(result) == N: 98 | for row in result: 99 | if len(row) != N: 100 | print(SIZE_ERROR) 101 | return False 102 | else: 103 | print(SIZE_ERROR) 104 | return False 105 | #check is it a magic square 106 | # line_sum = (N * (N ** 2 + 1)) / 2 107 | line_sum = sum(result[0]) 108 | for row in result: 109 | if sum(row) != line_sum: 110 | print(MS_ERROR) 111 | return False 112 | for col in zip(*result): 113 | if sum(col) != line_sum: 114 | print(MS_ERROR) 115 | return False 116 | if sum([result[i][i] for i in range(N)]) != line_sum: 117 | print(MS_ERROR) 118 | return False 119 | if sum([result[i][N - i - 1] for i in range(N)]) != line_sum: 120 | print(MS_ERROR) 121 | return False 122 | 123 | #check is it normal ms 124 | good_set = set(range(1, N ** 2 + 1)) 125 | user_set = set([result[i][j] for i in range(N) for j in range(N)]) 126 | if good_set != user_set: 127 | print(NORMAL_MS_ERROR) 128 | return False 129 | #check it is the square based on input 130 | for i in range(N): 131 | for j in range(N): 132 | if in_square[i][j] and in_square[i][j] != result[i][j]: 133 | print(NOT_BASED_ERROR) 134 | return False 135 | return True 136 | 137 | 138 | assert check_solution(checkio, 139 | [[2, 7, 6], 140 | [9, 5, 1], 141 | [4, 3, 0]]), "1st example" 142 | 143 | assert check_solution(checkio, 144 | [[0, 0, 0], 145 | [0, 5, 0], 146 | [0, 0, 0]]), "2nd example" 147 | 148 | assert check_solution(checkio, 149 | [[1, 15, 14, 4], 150 | [12, 0, 0, 9], 151 | [8, 0, 0, 5], 152 | [13, 3, 2, 16]]), "3rd example" 153 | -------------------------------------------------------------------------------- /haunted-house.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | DIRS = {"N": -4, "S": 4, "E": 1, "W": -1} 4 | 5 | 6 | def getRoomDir(house, number): 7 | room_dir = [ch for ch in "NWES" if ch not in house[number - 1]] 8 | if number % 4 == 1 and "W" in room_dir: 9 | room_dir.remove("W") 10 | if not number % 4 and "E" in room_dir: 11 | room_dir.remove("E") 12 | if number <= 4 and "N" in room_dir: 13 | room_dir.remove("N") 14 | if number > 12 and "S" in room_dir: 15 | room_dir.remove("S") 16 | return room_dir 17 | 18 | 19 | def getDis(house, start): 20 | dis = dict() 21 | dis[start] = 0 22 | toGo = [start] 23 | visited = [start] 24 | while toGo: 25 | room = toGo.pop(0) 26 | for my_dir in getRoomDir(house, room): 27 | nxtRoom = room + DIRS[my_dir] 28 | if nxtRoom not in visited: 29 | visited.append(nxtRoom) 30 | dis[nxtRoom] = dis[room] + 1 31 | toGo.append(nxtRoom) 32 | return dis 33 | 34 | 35 | def checkio(house, stephan, ghost): 36 | from random import choice 37 | 38 | if stephan == 1: 39 | return 'N' 40 | 41 | DIRS = {"N": -4, "S": 4, "E": 1, "W": -1} 42 | 43 | disExit = getDis(house, 1) 44 | 45 | disGhost = getDis(house, ghost) 46 | if disGhost[stephan] > 2: 47 | my_dirs, my_dist = "", 1000 48 | for my_dir in getRoomDir(house, stephan): 49 | if disExit[stephan + DIRS[my_dir]] < my_dist: 50 | my_dirs, my_dist = my_dir, disExit[stephan + DIRS[my_dir]] 51 | elif disExit[stephan + DIRS[my_dir]] == my_dist: 52 | my_dirs += my_dir 53 | my_dir = choice(my_dirs) 54 | 55 | return my_dir 56 | 57 | my_dirs, my_dist = "", 0 58 | for my_dir in getRoomDir(house, stephan): 59 | if disGhost[stephan + DIRS[my_dir]] > my_dist: 60 | my_dirs, my_dist = my_dir, disGhost[stephan + DIRS[my_dir]] 61 | elif disGhost[stephan + DIRS[my_dir]] == my_dist: 62 | my_dirs += my_dir 63 | 64 | dirs = my_dirs 65 | 66 | my_dirs, my_dist = "", 1000 67 | for my_dir in dirs: 68 | if disExit[stephan + DIRS[my_dir]] < my_dist: 69 | my_dirs, my_dist = my_dir, disExit[stephan + DIRS[my_dir]] 70 | elif disExit[stephan + DIRS[my_dir]] == my_dist: 71 | my_dirs += my_dir 72 | 73 | my_dirs = [my_dir for my_dir in my_dirs if len(getRoomDir(house, stephan+DIRS[my_dir])) != 1] 74 | print my_dirs 75 | my_dir = choice(my_dirs) 76 | 77 | 78 | return my_dir 79 | 80 | 81 | if __name__ == '__main__': 82 | #This part is using only for self-checking and not necessary for auto-testing 83 | from random import choice 84 | 85 | DIRS = {"N": -4, "S": 4, "E": 1, "W": -1} 86 | 87 | def check_solution(func, house): 88 | stephan = 16 89 | ghost = 1 90 | for step in range(30): 91 | direction = func(house[:], stephan, ghost) 92 | if direction in house[stephan - 1]: 93 | print('Stefan ran into a closed door. It was hurt.') 94 | return False 95 | if stephan == 1 and direction == "N": 96 | print('Stefan has escaped.') 97 | return True 98 | stephan += DIRS[direction] 99 | if ((direction == "W" and stephan % 4 == 0) or (direction == "E" and stephan % 4 == 1) or 100 | (stephan < 1) or (stephan > 16)): 101 | print('Stefan has gone out into the darkness.') 102 | return False 103 | sx, sy = (stephan - 1) % 4, (stephan - 1) // 4 104 | ghost_dirs = [ch for ch in "NWES" if ch not in house[ghost - 1]] 105 | if ghost % 4 == 1 and "W" in ghost_dirs: 106 | ghost_dirs.remove("W") 107 | if not ghost % 4 and "E" in ghost_dirs: 108 | ghost_dirs.remove("E") 109 | if ghost <= 4 and "N" in ghost_dirs: 110 | ghost_dirs.remove("N") 111 | if ghost > 12 and "S" in ghost_dirs: 112 | ghost_dirs.remove("S") 113 | 114 | ghost_dir, ghost_dist = "", 1000 115 | for d in ghost_dirs: 116 | new_ghost = ghost + DIRS[d] 117 | gx, gy = (new_ghost - 1) % 4, (new_ghost - 1) // 4 118 | dist = (gx - sx) ** 2 + (gy - sy) ** 2 119 | if ghost_dist > dist: 120 | ghost_dir, ghost_dist = d, dist 121 | elif ghost_dist == dist: 122 | ghost_dir += d 123 | ghost_move = choice(ghost_dir) 124 | ghost += DIRS[ghost_move] 125 | if ghost == stephan: 126 | print('The ghost caught Stephan.') 127 | return False 128 | print("Too many moves.") 129 | return False 130 | 131 | assert check_solution(checkio, 132 | ["", "S", "S", "", 133 | "E", "NW", "NS", "", 134 | "E", "WS", "NS", "", 135 | "", "N", "N", ""]), "1st example" 136 | assert check_solution(checkio, 137 | ["", "", "", "", 138 | "E", "ESW", "ESW", "W", 139 | "E", "ENW", "ENW", "W", 140 | "", "", "", ""]), "2nd example" 141 | check_solution(checkio, ["", "", "ES", "W", "E", "W", "N", "", "E", "WS", "S", "", "", "N", "N", ""]) 142 | -------------------------------------------------------------------------------- /open-labyrinth.py: -------------------------------------------------------------------------------- 1 | __author__ = 'jingyuan' 2 | 3 | 4 | class position: 5 | def __init__(self, x, y): 6 | self.x = x 7 | self.y = y 8 | self.g = 20 - self.x - self.y 9 | self.h = self.x + self.y - 2 10 | 11 | def setFrom(self, p): 12 | self.frm = p 13 | self.h = p.getH() + 1 14 | 15 | def getX(self): 16 | return self.x 17 | 18 | def getY(self): 19 | return self.y 20 | 21 | def getG(self): 22 | return self.g 23 | 24 | def getH(self): 25 | return self.h 26 | 27 | def getF(self): 28 | return self.g + self.h 29 | 30 | 31 | class maze: 32 | def __init__(self, data): 33 | self.data = data 34 | self.o = [] 35 | self.c = [] 36 | self.pos = [] 37 | for i in range(0, 12): 38 | self.pos.append([]) 39 | for i in range(0, 12): 40 | for j in range(0, 12): 41 | self.pos[i].append(position(i, j)) 42 | 43 | def do(self, p, f): 44 | if self.data[p.getX()][p.getY()] == 0 and p not in self.c: 45 | if p not in self.o: 46 | self.o.append(p) 47 | p.setFrom(f) 48 | else: 49 | if f.getH() + 1 < p.getH(): 50 | p.setFrom(f) 51 | 52 | def nextStep(self): 53 | f = 10000 54 | ret = None 55 | for p in self.o: 56 | if p.f() <= f: 57 | ret = p 58 | self.o.remove(ret) 59 | return ret 60 | 61 | def backTrace(self): 62 | ls = [] 63 | p = self.pos[10][10] 64 | while p != self.pos[1][1]: 65 | p, post = p.frm, p 66 | if p.getX() - post.getX() == 1: 67 | ls.append('N') 68 | elif p.getX() - post.getX() == -1: 69 | ls.append('S') 70 | elif p.getY() - post.getY() == 1: 71 | ls.append('W') 72 | else: 73 | ls.append('E') 74 | return ls 75 | 76 | def walk(self): 77 | p = self.pos[1][1] 78 | while p.getX() != 10 or p.getY() != 10: 79 | self.c.append(p) 80 | north = self.pos[p.getX()][p.getY() - 1] 81 | self.do(north, p) 82 | south = self.pos[p.getX()][p.getY() + 1] 83 | self.do(south, p) 84 | west = self.pos[p.getX() - 1][p.getY()] 85 | self.do(west, p) 86 | east = self.pos[p.getX() + 1][p.getY()] 87 | self.do(east, p) 88 | p = self.nextStep() 89 | return ''.join(self.backTrace()[-1::-1]) 90 | 91 | 92 | def checkio(data): 93 | m = maze(data) 94 | return m.walk() 95 | 96 | #Some hints 97 | #Look to graph search algorithms 98 | #Don't confuse these with tree search algorithms 99 | 100 | 101 | #This code using only for self-checking and not necessary for auto-testing 102 | 103 | 104 | def checkio2(labyrinth): 105 | sX, sY = 1, 1 106 | eX, eY = 10, 10 107 | paths = [(sX, sY, '')] 108 | visited = [(sX, sY)] 109 | while len(paths): 110 | x, y, p = paths.pop(0) 111 | if x == eX and y == eY: 112 | return p 113 | for i, j, s in [(x + 1, y, 'S'), (x - 1, y, 'N'), (x, y + 1, 'E'), (x, y - 1, 'W')]: 114 | if labyrinth[i][j] != 1 and (i, j) not in visited: # the borders are always 1 115 | visited.append((i, j)) 116 | paths.append((i, j, p + s)) 117 | 118 | 119 | if __name__ == '__main__': 120 | print(checkio2([ 121 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 122 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 123 | [1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1], 124 | [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], 125 | [1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1], 126 | [1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1], 127 | [1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], 128 | [1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1], 129 | [1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1], 130 | [1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1], 131 | [1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1], 132 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])) 133 | #be careful with infinity loop 134 | print(checkio([ 135 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 136 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 137 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 138 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 139 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 140 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 141 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 142 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 143 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 144 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 145 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 146 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] 147 | ])) 148 | print(checkio([ 149 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 150 | [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], 151 | [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1], 152 | [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], 153 | [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1], 154 | [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], 155 | [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1], 156 | [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], 157 | [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1], 158 | [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], 159 | [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1], 160 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 161 | ])) 162 | print(checkio([ 163 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 164 | [1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1], 165 | [1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1], 166 | [1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1], 167 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 168 | [1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1], 169 | [1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1], 170 | [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], 171 | [1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1], 172 | [1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1], 173 | [1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1], 174 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] 175 | ])) --------------------------------------------------------------------------------