diff --git a/EXERCISES.txt b/EXERCISES.txt index 8ab5e8b1dc6..db088fbce31 100644 --- a/EXERCISES.txt +++ b/EXERCISES.txt @@ -2,22 +2,53 @@ bob rna-transcription matrix word-count +twelve-days +accumulate anagram beer-song nucleotide-count +series +saddle-points +largest-series-product +octal +ocr-numbers +difference-of-squares point-mutations +proverb phone-number +pascals-triangle +allergies grade-school robot-name +minesweeper etl +sublist leap +sum-of-multiples space-age +strain grains gigasecond +palindrome-products +kindergarten-garden +meetup triangle +trinary scrabble-score +secret-handshake sieve +nth-prime +luhn +crypto-square roman-numerals binary prime-factors raindrops +atbash-cipher +wordy +pythagorean-triplet +hamming +house +simple-cipher +hexadecimal +queen-attack diff --git a/accumulate/accumulate_test.py b/accumulate/accumulate_test.py new file mode 100644 index 00000000000..9edc6fca547 --- /dev/null +++ b/accumulate/accumulate_test.py @@ -0,0 +1,38 @@ +from accumulate import accumulate + +import unittest + + +class AccumulateTest(unittest.TestCase): + def test_empty_sequence(self): + self.assertEqual([], accumulate([], lambda x: x/2)) + + def test_pow(self): + self.assertEqual([1, 4, 9, 16, 25], accumulate([1, 2, 3, 4, 5], + lambda x: x*x)) + + def test_divmod(self): + inp = [10, 17, 23] + out = [(1, 3), (2, 3), (3, 2)] + self.assertEqual(out, accumulate(inp, lambda x: divmod(x, 7))) + + def test_composition(self): + inp = [10, 17, 23] + fn1 = lambda x: divmod(x, 7) + fn2 = lambda x: 7*x[0]+x[1] + self.assertEqual(inp, accumulate(accumulate(inp, fn1), fn2)) + + def test_capitalize(self): + inp = ['hello', 'world'] + out = ['HELLO', 'WORLD'] + self.assertEqual(out, accumulate(inp, str.upper)) + + def test_recursive(self): + inp = list('abc') + out = [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3'], ['c1', 'c2', 'c3']] + fn = lambda x: accumulate(list('123'), lambda y: x+y) + self.assertEqual(out, accumulate(inp, fn)) + + +if __name__ == '__main__': + unittest.main() diff --git a/accumulate/example.py b/accumulate/example.py new file mode 100644 index 00000000000..ab9ca8054e8 --- /dev/null +++ b/accumulate/example.py @@ -0,0 +1,8 @@ +# [op(x) for x in seq] would be nice but trivial + + +def accumulate(seq,op): + res = [] + for el in seq: + res.append(op(el)) + return res diff --git a/allergies/allergies_test.py b/allergies/allergies_test.py new file mode 100644 index 00000000000..c349e71d4ea --- /dev/null +++ b/allergies/allergies_test.py @@ -0,0 +1,43 @@ +try: + from allergies import Allergies +except ImportError: + raise SystemExit('Could not find allergies.py. Does it exist?') + +import unittest + + +class AllergiesTests(unittest.TestCase): + + def test_no_allergies_means_not_allergic(self): + allergies = Allergies(0) + self.assertFalse(allergies.is_allergic_to('peanuts')) + self.assertFalse(allergies.is_allergic_to('cats')) + self.assertFalse(allergies.is_allergic_to('strawberries')) + + def test_is_allergic_to_eggs(self): + self.assertTrue(Allergies(1).is_allergic_to('eggs')) + + def test_has_the_right_allergies(self): + allergies = Allergies(5) + self.assertTrue(allergies.is_allergic_to('eggs')) + self.assertTrue(allergies.is_allergic_to('shellfish')) + self.assertFalse(allergies.is_allergic_to('strawberries')) + + def test_no_allergies_at_all(self): + self.assertEqual([], Allergies(0).list) + + def test_allergic_to_just_peanuts(self): + self.assertEqual(['peanuts'], Allergies(2).list) + + def test_allergic_to_everything(self): + self.assertEqual( + ('eggs peanuts shellfish strawberries tomatoes ' + 'chocolate pollen cats').split(), + Allergies(255).list) + + def test_ignore_non_allergen_score_parts(self): + self.assertEqual(['eggs'], Allergies(257).list) + + +if __name__ == '__main__': + unittest.main() diff --git a/allergies/example.py b/allergies/example.py new file mode 100644 index 00000000000..37d779330e4 --- /dev/null +++ b/allergies/example.py @@ -0,0 +1,22 @@ +def powers_of_2(n): + """Return a list of the powers of 2 whose sum is the input number.""" + return [2 ** exponent + for exponent, bit in enumerate(bin(n)[:1:-1]) + if bit == '1'] + + +class Allergies(object): + + __allergens = {2 ** exponent: allergen + for exponent, allergen in enumerate( + ("eggs peanuts shellfish strawberries tomatoes " + "chocolate pollen cats").split())} + + def __init__(self, score): + self.score = score + self.list = [self.__allergens[p] + for p in powers_of_2(score) + if p in self.__allergens] + + def is_allergic_to(self, allergen): + return allergen in self.list diff --git a/atbash-cipher/atbash_cipher_test.py b/atbash-cipher/atbash_cipher_test.py new file mode 100644 index 00000000000..e42b3c90ac5 --- /dev/null +++ b/atbash-cipher/atbash_cipher_test.py @@ -0,0 +1,45 @@ +try: + from atbash_cipher import encode, decode +except ImportError: + raise SystemExit('Could not find atbash_cipher.py. Does it exist?') + +import unittest + + +class AtbashCipherTest(unittest.TestCase): + def test_encode_no(self): + self.assertEqual("ml", encode("no")) + + def test_encode_yes(self): + self.assertEqual("bvh", encode("yes")) + + def test_encode_OMG(self): + self.assertEqual("lnt", encode("OMG")) + + def test_encode_O_M_G(self): + self.assertEqual("lnt", encode("O M G")) + + def test_encode_long_word(self): + self.assertEqual("nrmwy oldrm tob", encode("mindblowingly")) + + def test_encode_numbers(self): + self.assertEqual("gvhgr mt123 gvhgr mt", + encode("Testing, 1 2 3, testing.")) + + def test_encode_sentence(self): + self.assertEqual("gifgs rhurx grlm", + encode("Truth is fiction.")) + + def test_encode_all_things(self): + plaintext = "The quick brown fox jumps over the lazy dog." + ciphertext = "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt" + self.assertEqual(ciphertext, encode(plaintext)) + + def test_decode_word(self): + self.assertEqual("exercism", decode("vcvix rhn")) + + def test_decode_sentence(self): + self.assertEqual("anobstacleisoftenasteppingstone", decode("zmlyh gzxov rhlug vmzhg vkkrm thglm v")) + +if __name__ == '__main__': + unittest.main() diff --git a/atbash-cipher/example.py b/atbash-cipher/example.py new file mode 100644 index 00000000000..021cd07d2bc --- /dev/null +++ b/atbash-cipher/example.py @@ -0,0 +1,14 @@ +from string import maketrans, lowercase, digits, punctuation, whitespace + +BLKSZ = 5 +trtbl = maketrans(lowercase+digits, "".join(reversed(lowercase))+digits) + +def base_trans(text): + return text.lower().translate(trtbl, punctuation+whitespace) + +def encode(plain): + cipher = base_trans(plain) + return " ".join([cipher[i:i+BLKSZ] for i in range(0,len(cipher),BLKSZ)]) + +def decode(ciphered): + return base_trans(ciphered) \ No newline at end of file diff --git a/crypto-square/crypto_square_test.py b/crypto-square/crypto_square_test.py new file mode 100644 index 00000000000..91294ad5b4f --- /dev/null +++ b/crypto-square/crypto_square_test.py @@ -0,0 +1,40 @@ +from crypto_square import encode, decode + +import unittest + +class CryptoSquareTest(unittest.TestCase): + def test_empty_plain(self): + self.assertEqual('', encode('')) + + def test_perfect_square(self): + self.assertEqual('wliod drwe', encode('WorldWide')) + + def test_almost_perfect_square(self): + self.assertEqual('oasny selde', encode('One day less')) + + def test_punctuation(self): + msg = "1, 2, 3, Go! Go, for God's sake!" + ciph = '1gga2 ook3f degos ors' + self.assertEqual(ciph, encode(msg)) + + def test_long_string(self): + msg = "Be who you are and say what you feel, because those who mind "\ + "don't matter and those who matter don't mind." + ciph = 'betcw tttne ayahm htdwn ouoao ehdus mtsro sfeit edyae tnewo '\ + 'oyehd rhnuw lodao tahbs onmmr aeend ai' + self.assertEqual(ciph, encode(msg)) + + def test_decode(self): + ciph = 'woree iorhu ssmtp eefei aiafn ildjs ulenf eotse vdoor iecey '\ + 'nfima trott tenyu hhytd' + msg = 'wheneveryoufindyourselfonthesideofthemajorityitistimetopausea'\ + 'ndreflect' + self.assertEqual(msg, decode(ciph)) + + def test_encode_decode(self): + msg = 'tensioniswhoyouthinkyoushouldberelaxationiswhoyouare' + self.assertEqual(msg, decode(encode(msg))) + + +if __name__ == '__main__': + unittest.main() diff --git a/crypto-square/example.py b/crypto-square/example.py new file mode 100644 index 00000000000..768c08e8419 --- /dev/null +++ b/crypto-square/example.py @@ -0,0 +1,43 @@ +import math +from string import punctuation,whitespace + +def encode(msg): + msg = msg.strip().translate(None,punctuation+whitespace).lower() + sqrsz = int(math.sqrt(len(msg))) + if sqrsz*sqrsz < len(msg): + sqrsz += 1 + + cols = [msg[i1::sqrsz] for i1 in range(sqrsz)] + cols_str = ''.join(cols) + return ' '.join(cols_str[i1:i1+5] for i1 in range(0,len(cols_str),5)) + +def decode(ciph): + ciph = ciph.strip().translate(None,punctuation+whitespace).lower() + sqrsz = int(math.sqrt(len(ciph))) + if sqrsz*sqrsz < len(ciph): + sqrsz += 1 + colsz, nbr_full_cols = divmod(len(ciph),sqrsz) + + # The matrix produced by the plaintext is in general irregular, and the + # last row is usually shorter than the others. Extract this row first + full_cols_str = ciph[:(colsz+1)*nbr_full_cols] + partial_cols_str = ciph[(colsz+1)*nbr_full_cols:] + last_row = full_cols_str[colsz::colsz+1] + + # Compute the string of all concatenated columns of the colsz X sqrsz + # matrix consisting of the first colsz rows of the plaintext (irregular) + # matrix + trimmed_full_cols = [full_cols_str[i1:i1+colsz] + for i1 in range(0,len(full_cols_str),colsz+1)] + partial_cols = [partial_cols_str[i1:i1+colsz] + for i1 in range(0,len(partial_cols_str),colsz)] + uniform_cols_str = ''.join(trimmed_full_cols + partial_cols) + + other_rows = [uniform_cols_str[i1::colsz] for i1 in range(colsz)] + return ''.join(other_rows+[last_row]) + +if __name__ == '__main__': + msg = 'ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots' + ciph = 'imtgd vsfea rwerm ayoog oanou uiont nnlvt wttdd esaoh ghnss eoau' + print(encode(msg)) + print(decode(ciph)) diff --git a/difference-of-squares/difference_of_squares_test.py b/difference-of-squares/difference_of_squares_test.py new file mode 100644 index 00000000000..728ff4c6f69 --- /dev/null +++ b/difference-of-squares/difference_of_squares_test.py @@ -0,0 +1,31 @@ +try: + from difference_of_squares import difference, square_of_sum, sum_of_squares +except ImportError: + raise SystemExit('Could not find difference_of_squares.py. Does it exist?') + +import unittest + + +class DifferenceOfSquaresTest(unittest.TestCase): + + def test_square_of_sum_5(self): + self.assertEqual(225, square_of_sum(5)) + + def test_sum_of_squares_5(self): + self.assertEqual(55, sum_of_squares(5)) + + def test_difference_5(self): + self.assertEqual(170, difference(5)) + + def test_square_of_sum_100(self): + self.assertEqual(25502500, square_of_sum(100)) + + def test_sum_of_squares_100(self): + self.assertEqual(338350, sum_of_squares(100)) + + def test_difference_100(self): + self.assertEqual(25164150, difference(100)) + + +if __name__ == '__main__': + unittest.main() diff --git a/difference-of-squares/example.py b/difference-of-squares/example.py new file mode 100644 index 00000000000..b2944ecf111 --- /dev/null +++ b/difference-of-squares/example.py @@ -0,0 +1,11 @@ +def square_of_sum(n): + sum_ = n * (n + 1) / 2 + return sum_ * sum_ + + +def sum_of_squares(n): + return sum(m * m for m in range(n + 1)) + + +def difference(n): + return square_of_sum(n) - sum_of_squares(n) diff --git a/hamming/example.py b/hamming/example.py new file mode 100644 index 00000000000..20026498987 --- /dev/null +++ b/hamming/example.py @@ -0,0 +1,2 @@ +def hamming(s1,s2): + return sum(1 for a,b in map(None,s1,s2) if a != b) diff --git a/hamming/hamming_test.py b/hamming/hamming_test.py new file mode 100644 index 00000000000..00c3d191400 --- /dev/null +++ b/hamming/hamming_test.py @@ -0,0 +1,42 @@ +from hamming import hamming + +import unittest + +# If the sequences have different lengths, assume the shorter one is extended +# with nucleotides in such a way to guarantee the extra nucleotides are all +# different between the two strands. + +class hammingdecimalTest(unittest.TestCase): + def test_hamming_empty(self): + self.assertEqual(0, hamming('','')) + + def test_hamming_onenucleotide_same(self): + self.assertEqual(0, hamming('A','A')) + + def test_hamming_onenucleotide_different(self): + self.assertEqual(1, hamming('A','G')) + + def test_hamming_short1(self): + self.assertEqual(1, hamming('AT','CT')) + + def test_hamming_short2(self): + self.assertEqual(2, hamming('AG','CT')) + + def test_hamming_large(self): + self.assertEqual(4, hamming('GGATCG','CCTGCG')) + + def test_hamming_small(self): + self.assertEqual(1, hamming('GGACGA','GGTCGA')) + + def test_hamming_very_long(self): + self.assertEqual(9, hamming('GGACGGATTCTG','AGGACGGATTCT')) + + def test_hamming_different_length1(self): + self.assertEqual(4, hamming('AAGCTAC','ACGTT')) + + def test_hamming_different_length2(self): + self.assertEqual(5, hamming('AAGCTAC','ACGTTACGTC')) + + +if __name__ == '__main__': + unittest.main() diff --git a/hexadecimal/example.py b/hexadecimal/example.py new file mode 100644 index 00000000000..513c5e6dd09 --- /dev/null +++ b/hexadecimal/example.py @@ -0,0 +1,12 @@ +def hexa(s): + s = s.lower() + if set(s) - set('0123456789abcdef'): + raise ValueError('Invalid hexadecimal string') + l = [ord(c) - ord('a') + 10 if c in 'abcdef' else ord(c) - ord('0') + for c in s] + return reduce(lambda x,y:x*16 + y, l, 0) + +if __name__ == '__main__': + print hexa('19ACE') + print hexa('100') + print hexa('dead') \ No newline at end of file diff --git a/hexadecimal/hexadecimal_test.py b/hexadecimal/hexadecimal_test.py new file mode 100644 index 00000000000..08f13b1c1d2 --- /dev/null +++ b/hexadecimal/hexadecimal_test.py @@ -0,0 +1,42 @@ +# To avoid trivial solutions, try to solve this problem without the +# function int(s, base=16) + +from hexadecimal import hexa + +import unittest + +class HexadecimalTest(unittest.TestCase): + def test_valid_hexa1(self): + self.assertEqual(1, hexa('1')) + + def test_valid_hexa2(self): + self.assertEqual(12, hexa('c')) + + def test_valid_hexa3(self): + self.assertEqual(16, hexa('10')) + + def test_valid_hexa4(self): + self.assertEqual(175, hexa('af')) + + def test_valid_hexa5(self): + self.assertEqual(256, hexa('100')) + + def test_valid_hexa6(self): + self.assertEqual(105166, hexa('19ACE')) + + def test_valid_hexa7(self): + self.assertEqual(0, hexa('000000')) + + def test_valid_hexa8(self): + self.assertEqual(16776960, hexa('ffff00')) + + def test_valid_hexa9(self): + self.assertEqual(65520, hexa('00fff0')) + + def test_invalid_hexa(self): + with self.assertRaises(ValueError): + hexa('carrot') + + +if __name__ == '__main__': + unittest.main() diff --git a/house/example.py b/house/example.py new file mode 100644 index 00000000000..de1d2e48625 --- /dev/null +++ b/house/example.py @@ -0,0 +1,24 @@ +parts = [('lay in', 'the house that Jack built'), + ('ate', 'the malt'), + ('killed', 'the rat'), + ('worried', 'the cat'), + ('tossed', 'the dog'), + ('milked', 'the cow with the crumpled horn'), + ('kissed', 'the maiden all forlorn'), + ('married', 'the man all tattered and torn'), + ('woke', 'the priest all shaven and shorn'), + ('kept', 'the rooster that crowed in the morn'), + ('belonged to', 'the farmer sowing his corn'), + ('', 'the horse and the hound and the horn')] + + +def _verse(n): + v = ['This is {}'.format(parts[n][1])] + v.extend(['that {0} {1}'.format(parts[i][0], parts[i][1]) + for i in range(n-1, -1, -1)]) + v[-1] += '.' + return '\n'.join(v) + + +def rhyme(): + return "\n\n".join(_verse(n) for n in range(len(parts))) diff --git a/house/house_test.py b/house/house_test.py new file mode 100644 index 00000000000..92b795be515 --- /dev/null +++ b/house/house_test.py @@ -0,0 +1,92 @@ +# Rhyme found in http://www.pitt.edu/~dash/type2035.html + +from house import rhyme + +import unittest + + +class VerseTest(unittest.TestCase): + def test_rhyme(self): + expected = 'This is the house that Jack built.\n\n'\ + 'This is the malt\n'\ + 'that lay in the house that Jack built.\n\n'\ + 'This is the rat\n'\ + 'that ate the malt\n'\ + 'that lay in the house that Jack built.\n\n'\ + 'This is the cat\n'\ + 'that killed the rat\n'\ + 'that ate the malt\n'\ + 'that lay in the house that Jack built.\n\n'\ + 'This is the dog\n'\ + 'that worried the cat\n'\ + 'that killed the rat\n'\ + 'that ate the malt\n'\ + 'that lay in the house that Jack built.\n\n'\ + 'This is the cow with the crumpled horn\n'\ + 'that tossed the dog\n'\ + 'that worried the cat\n'\ + 'that killed the rat\n'\ + 'that ate the malt\n'\ + 'that lay in the house that Jack built.\n\n'\ + 'This is the maiden all forlorn\n'\ + 'that milked the cow with the crumpled horn\n'\ + 'that tossed the dog\n'\ + 'that worried the cat\n'\ + 'that killed the rat\n'\ + 'that ate the malt\n'\ + 'that lay in the house that Jack built.\n\n'\ + 'This is the man all tattered and torn\n'\ + 'that kissed the maiden all forlorn\n'\ + 'that milked the cow with the crumpled horn\n'\ + 'that tossed the dog\n'\ + 'that worried the cat\n'\ + 'that killed the rat\n'\ + 'that ate the malt\n'\ + 'that lay in the house that Jack built.\n\n'\ + 'This is the priest all shaven and shorn\n'\ + 'that married the man all tattered and torn\n'\ + 'that kissed the maiden all forlorn\n'\ + 'that milked the cow with the crumpled horn\n'\ + 'that tossed the dog\n'\ + 'that worried the cat\n'\ + 'that killed the rat\n'\ + 'that ate the malt\n'\ + 'that lay in the house that Jack built.\n\n'\ + 'This is the rooster that crowed in the morn\n'\ + 'that woke the priest all shaven and shorn\n'\ + 'that married the man all tattered and torn\n'\ + 'that kissed the maiden all forlorn\n'\ + 'that milked the cow with the crumpled horn\n'\ + 'that tossed the dog\n'\ + 'that worried the cat\n'\ + 'that killed the rat\n'\ + 'that ate the malt\n'\ + 'that lay in the house that Jack built.\n\n'\ + 'This is the farmer sowing his corn\n'\ + 'that kept the rooster that crowed in the morn\n'\ + 'that woke the priest all shaven and shorn\n'\ + 'that married the man all tattered and torn\n'\ + 'that kissed the maiden all forlorn\n'\ + 'that milked the cow with the crumpled horn\n'\ + 'that tossed the dog\n'\ + 'that worried the cat\n'\ + 'that killed the rat\n'\ + 'that ate the malt\n'\ + 'that lay in the house that Jack built.\n\n'\ + 'This is the horse and the hound and the horn\n'\ + 'that belonged to the farmer sowing his corn\n'\ + 'that kept the rooster that crowed in the morn\n'\ + 'that woke the priest all shaven and shorn\n'\ + 'that married the man all tattered and torn\n'\ + 'that kissed the maiden all forlorn\n'\ + 'that milked the cow with the crumpled horn\n'\ + 'that tossed the dog\n'\ + 'that worried the cat\n'\ + 'that killed the rat\n'\ + 'that ate the malt\n'\ + 'that lay in the house that Jack built.' + self.assertEqual(expected, rhyme()) + + +if __name__ == '__main__': + unittest.main() diff --git a/kindergarten-garden/example.py b/kindergarten-garden/example.py new file mode 100644 index 00000000000..0544c440b1c --- /dev/null +++ b/kindergarten-garden/example.py @@ -0,0 +1,18 @@ +class Garden(object): + + __plant_names = {"C": "Clover", "G": "Grass", + "R": "Radishes", "V": "Violets"} + + def __init__(self, diagram, + students=("Alice Bob Charlie David " + "Eve Fred Ginny Harriet " + "Ileana Joseph Kincaid Larry").split()): + self.plant_rows = diagram.split() + self.students = sorted(students) + + def plants(self, student): + slot_start = self.students.index(student) * 2 + slot = slice(slot_start, slot_start + 2) + return [self.__plant_names[abbrev] + for abbrev in (self.plant_rows[0][slot] + + self.plant_rows[1][slot])] diff --git a/kindergarten-garden/kindergarten_garden_test.py b/kindergarten-garden/kindergarten_garden_test.py new file mode 100644 index 00000000000..04011a0a1b4 --- /dev/null +++ b/kindergarten-garden/kindergarten_garden_test.py @@ -0,0 +1,37 @@ +import unittest +from garden import Garden + + +class KindergartenGardenTests(unittest.TestCase): + + def test_alices_garden(self): + self.assertEqual("Radishes Clover Grass Grass".split(), + Garden("RC\nGG").plants("Alice")) + + def test_bob_and_charlies_gardens(self): + garden = Garden("VVCCGG\nVVCCGG") + self.assertEqual(["Clover"] * 4, garden.plants("Bob")) + self.assertEqual(["Grass"] * 4, garden.plants("Charlie")) + + def test_full_garden(self): + garden = Garden("VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV") + self.assertEqual("Violets Radishes Violets Radishes".split(), + garden.plants("Alice")) + self.assertEqual("Clover Grass Clover Clover".split(), + garden.plants("Bob")) + self.assertEqual("Grass Clover Clover Grass".split(), + garden.plants("Kincaid")) + self.assertEqual("Grass Violets Clover Violets".split(), + garden.plants("Larry")) + + def test_disordered_test(self): + garden = Garden("VCRRGVRG\nRVGCCGCV", + students="Samantha Patricia Xander Roger".split()) + self.assertEqual("Violets Clover Radishes Violets".split(), + garden.plants("Patricia")) + self.assertEqual("Radishes Grass Clover Violets".split(), + garden.plants("Xander")) + + +if __name__ == '__main__': + unittest.main() diff --git a/largest-series-product/example.py b/largest-series-product/example.py new file mode 100644 index 00000000000..daa4cde478f --- /dev/null +++ b/largest-series-product/example.py @@ -0,0 +1,19 @@ +from functools import reduce +from operator import mul + + +class Series(object): + def __init__(self, number_string): + self.digits = [int(d) for d in number_string] + + def slices(self, length): + if not 1 <= length <= len(self.digits): + raise ValueError("Invalid slice length for this series: " + + str(length)) + return [self.digits[i:i + length] + for i in range(len(self.digits) - length + 1)] + + def largest_product(self, length): + if length == 0: + return 1 + return max(reduce(mul, slc) for slc in self.slices(length)) diff --git a/largest-series-product/largest_series_product_test.py b/largest-series-product/largest_series_product_test.py new file mode 100644 index 00000000000..474dfea6d86 --- /dev/null +++ b/largest-series-product/largest_series_product_test.py @@ -0,0 +1,44 @@ +try: + from series import Series +except ImportError: + raise SystemExit('Could not find series.py. Does it exist?') + +import unittest + + +class SeriesTest(unittest.TestCase): + def test_slices_of_two(self): + self.assertEqual([[9, 7], [7, 8], [8, 6], [6, 7], + [7, 5], [5, 6], [6, 4]], + Series("97867564").slices(2)) + + def test_overly_long_slice(self): + self.assertRaisesRegexp(ValueError, + "^Invalid slice length for this series: 4$", + Series("012").slices, 4) + + def test_largest_product_of_2(self): + self.assertEqual(72, Series("0123456789").largest_product(2)) + + def test_tiny_number(self): + self.assertEqual(9, Series("19").largest_product(2)) + + def test_largest_product_of_3(self): + self.assertEqual(270, Series("1027839564").largest_product(3)) + + def test_big_number(self): + self.assertEqual(28350, + Series("52677741234314237566414902593461595376319419" + "139427").largest_product(6)) + + def test_identity(self): + self.assertEqual(1, Series("").largest_product(0)) + + def test_slices_bigger_than_number(self): + self.assertRaisesRegexp(ValueError, + "^Invalid slice length for this series: 4$", + Series("012").largest_product, 4) + + +if __name__ == '__main__': + unittest.main() diff --git a/luhn/example.py b/luhn/example.py new file mode 100644 index 00000000000..5d061b568d9 --- /dev/null +++ b/luhn/example.py @@ -0,0 +1,20 @@ +class Luhn(object): + def __init__(self, number): + self.number = number + + def addends(self): + old_digits = [int(d) for d in str(self.number)] + luhn_transform = lambda n: (2 * n - 9) if (n > 4) else (2 * n) + return [(luhn_transform(n) if (i % 2 == 0) else n) + for i, n in enumerate(old_digits, start=len(old_digits) % 2)] + + def checksum(self): + return sum(self.addends()) % 10 + + def is_valid(self): + return self.checksum() == 0 + + @staticmethod + def create(n): + diff = (10 - Luhn(n * 10).checksum()) % 10 + return 10 * n + diff diff --git a/luhn/luhn_test.py b/luhn/luhn_test.py new file mode 100644 index 00000000000..994ff1014b7 --- /dev/null +++ b/luhn/luhn_test.py @@ -0,0 +1,39 @@ +try: + from luhn import Luhn +except ImportError: + raise SystemExit('Could not find luhn.py. Does it exist?') + +import unittest + + +class LuhnTests(unittest.TestCase): + def test_addends(self): + self.assertEqual([1, 4, 1, 4, 1], Luhn(12121).addends()) + + def test_addends_large(self): + self.assertEqual([7, 6, 6, 1], Luhn(8631).addends()) + + def test_checksum1(self): + self.assertEqual(2, Luhn(4913).checksum()) + + def test_ckecksum2(self): + self.assertEqual(1, Luhn(201773).checksum()) + + def test_invalid_number(self): + self.assertFalse(Luhn(738).is_valid()) + + def test_valid_number(self): + self.assertTrue(Luhn(8739567).is_valid()) + + def test_create_valid_number1(self): + self.assertEqual(1230, Luhn.create(123)) + + def test_create_valid_number2(self): + self.assertEqual(8739567, Luhn.create(873956)) + + def test_create_valid_number3(self): + self.assertEqual(8372637564, Luhn.create(837263756)) + + +if __name__ == '__main__': + unittest.main() diff --git a/meetup/example.py b/meetup/example.py new file mode 100644 index 00000000000..2abeb1d1308 --- /dev/null +++ b/meetup/example.py @@ -0,0 +1,17 @@ +from calendar import Calendar + + +def meetup_day(year, month, day_of_the_week, which): + candidates = [date + for date in Calendar().itermonthdates(year, month) + if date.month == month + if date.strftime('%A') == day_of_the_week] + return _choice(which)(candidates) + + +def _choice(which): + if which == 'teenth': + return lambda dates: next(d for d in dates if 13 <= d.day <= 19) + + ix = -1 if (which == 'last') else (int(which[0]) - 1) + return lambda dates: dates[ix] diff --git a/meetup/meetup_test.py b/meetup/meetup_test.py new file mode 100644 index 00000000000..54304b1a6eb --- /dev/null +++ b/meetup/meetup_test.py @@ -0,0 +1,41 @@ +from datetime import date +import unittest + +from meetup import meetup_day + + +class MeetupTest(unittest.TestCase): + def test_monteenth_of_may_2013(self): + self.assertEqual(date(2013, 5, 13), + meetup_day(2013, 5, 'Monday', 'teenth')) + + def test_saturteenth_of_february_2013(self): + self.assertEqual(date(2013, 2, 16), + meetup_day(2013, 2, 'Saturday', 'teenth')) + + def test_first_tuesday_of_may_2013(self): + self.assertEqual(date(2013, 5, 7), + meetup_day(2013, 5, 'Tuesday', '1st')) + + def test_second_monday_of_april_2013(self): + self.assertEqual(date(2013, 4, 8), + meetup_day(2013, 4, 'Monday', '2nd')) + + def test_third_thursday_of_september_2013(self): + self.assertEqual(date(2013, 9, 19), + meetup_day(2013, 9, 'Thursday', '3rd')) + + def test_fourth_sunday_of_march_2013(self): + self.assertEqual(date(2013, 3, 24), + meetup_day(2013, 3, 'Sunday', '4th')) + + def test_last_thursday_of_october_2013(self): + self.assertEqual(date(2013, 10, 31), + meetup_day(2013, 10, 'Thursday', 'last')) + + def test_last_wednesday_of_february_2012(self): + self.assertEqual(date(2012, 2, 29), + meetup_day(2012, 2, 'Wednesday', 'last')) + +if __name__ == '__main__': + unittest.main() diff --git a/minesweeper/example.py b/minesweeper/example.py new file mode 100644 index 00000000000..27f1559e2cb --- /dev/null +++ b/minesweeper/example.py @@ -0,0 +1,36 @@ +def board(inp): + verify_board(inp) + rowlen = len(inp[0]) + collen = len(inp) + b = [list(r) for r in inp] + for i1 in range(collen): + for i2 in range(rowlen): + if b[i1][i2] != ' ': + continue + cnt = inp[i1-1][i2-1:i2+2].count('*') + \ + inp[i1][i2-1:i2+2].count('*') + \ + inp[i1+1][i2-1:i2+2].count('*') + if cnt == 0: + continue + b[i1][i2] = str(cnt) + return ["".join(r) for r in b] + +def verify_board(inp): + # Null board or a null row + if not inp or not all(r for r in inp): + raise ValueError("Invalid board") + # Rows with different lengths + rowlen = len(inp[0]) + collen = len(inp) + if not all(len(r)==rowlen for r in inp): + raise ValueError("Invalid board") + # Unknown character in board + cset = set() + for r in inp: + cset.update(r) + if cset - set('+- *|'): + raise ValueError("Invalid board") + # Borders not as expected + if any(inp[i1] != '+'+'-'*(rowlen-2)+'+' for i1 in [0,-1]) or \ + any(inp[i1][i2] != '|' for i1 in range(1,collen-1) for i2 in [0,-1]): + raise ValueError("Invalid board") \ No newline at end of file diff --git a/minesweeper/minesweeper_test.py b/minesweeper/minesweeper_test.py new file mode 100644 index 00000000000..241ecffbde4 --- /dev/null +++ b/minesweeper/minesweeper_test.py @@ -0,0 +1,91 @@ +try: + from minesweeper import board +except ImportError: + raise SystemExit('Could not find minesweeper.py. Does it exist?') + +import unittest + +class MinesweeperTest(unittest.TestCase): + def test_board1(self): + inp = ["+------+", "| * * |", "| * |", "| * |", "| * *|", + "| * * |", "| |", "+------+"] + out = ["+------+", "|1*22*1|", "|12*322|", "| 123*2|", "|112*4*|", + "|1*22*2|", "|111111|", "+------+"] + self.assertEqual(out, board(inp)) + + @unittest.skip("Not implemented yet") + def test_board2(self): + inp = ["+-----+", "| * * |", "| |", "| * |", "| * *|", + "| * * |", "+-----+"] + out = ["+-----+", "|1*2*1|", "|11322|", "| 12*2|", "|12*4*|", + "|1*3*2|", "+-----+"] + self.assertEqual(out, board(inp)) + + @unittest.skip("Not implemented yet") + def test_board3(self): + inp = ["+-----+", "| * * |", "+-----+"] + out = ["+-----+", "|1*2*1|", "+-----+"] + self.assertEqual(out, board(inp)) + + @unittest.skip("Not implemented yet") + def test_board4(self): + inp = ["+-+", "|*|", "| |", "|*|", "| |", "| |", "+-+"] + out = ["+-+", "|*|", "|2|", "|*|", "|1|", "| |", "+-+"] + self.assertEqual(out, board(inp)) + + @unittest.skip("Not implemented yet") + def test_board5(self): + inp = ["+-+", "|*|", "+-+"] + out = ["+-+", "|*|", "+-+"] + self.assertEqual(out, board(inp)) + + @unittest.skip("Not implemented yet") + def test_board6(self): + inp = ["+--+", "|**|", "|**|", "+--+"] + out = ["+--+", "|**|", "|**|", "+--+"] + self.assertEqual(out, board(inp)) + + @unittest.skip("Not implemented yet") + def test_board7(self): + inp = ["+--+", "|**|", "|**|", "+--+"] + out = ["+--+", "|**|", "|**|", "+--+"] + self.assertEqual(out, board(inp)) + + @unittest.skip("Not implemented yet") + def test_board8(self): + inp = ["+---+", "|***|", "|* *|", "|***|", "+---+"] + out = ["+---+", "|***|", "|*8*|", "|***|", "+---+"] + self.assertEqual(out, board(inp)) + + @unittest.skip("Not implemented yet") + def test_board9(self): + inp = ["+-----+", "| |", "| * |", "| |", "| |", + "| * |", "+-----+"] + out = ["+-----+", "| 111|", "| 1*1|", "| 111|", "|111 |", + "|1*1 |", "+-----+"] + self.assertEqual(out, board(inp)) + + @unittest.skip("Not implemented yet") + def test_different_len(self): + inp = ["+-+", "| |", "|* |", "| |", "+-+"] + with self.assertRaises(ValueError) as context: + board(inp) + self.assertEqual(context.exception.message, 'Invalid board') + + @unittest.skip("Not implemented yet") + def test_faulty_border(self): + inp = ["+-----+", "* * |", "+-- --+"] + with self.assertRaises(ValueError) as context: + board(inp) + self.assertEqual(context.exception.message, 'Invalid board') + + @unittest.skip("Not implemented yet") + def test_invalid_char(self): + inp = ["+-----+", "|X * |", "+-----+"] + with self.assertRaises(ValueError) as context: + board(inp) + self.assertEqual(context.exception.message, 'Invalid board') + + +if __name__ == '__main__': + unittest.main() diff --git a/nth-prime/example.py b/nth-prime/example.py new file mode 100644 index 00000000000..d997d8a29b1 --- /dev/null +++ b/nth-prime/example.py @@ -0,0 +1,31 @@ +from itertools import count +from math import sqrt + + +def nth_prime(n): + known = [] + candidates = prime_candidates() + + def is_prime(m): + sqrt_m = sqrt(m) + for k in known: + if k > sqrt_m: + return True + elif m % k == 0: + return False + return True + + while len(known) < n: + x = next(candidates) + if is_prime(x): + known.append(x) + + return known[n - 1] + + +def prime_candidates(): + yield 2 + yield 3 + for n in count(6, 6): + yield n - 1 + yield n + 1 diff --git a/nth-prime/nth_prime_test.py b/nth-prime/nth_prime_test.py new file mode 100644 index 00000000000..761e07ce105 --- /dev/null +++ b/nth-prime/nth_prime_test.py @@ -0,0 +1,25 @@ +try: + from prime import nth_prime +except ImportError: + raise SystemExit('Could not find prime.py. Does it exist?') + +import unittest + + +class NthPrimeTests(unittest.TestCase): + def test_first_prime(self): + self.assertEqual(2, nth_prime(1)) + + def test_sixth_prime(self): + self.assertEqual(13, nth_prime(6)) + + def test_first_twenty_primes(self): + self.assertEqual([2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71], + [nth_prime(n) for n in range(1, 21)]) + + def test_prime_no_10000(self): + self.assertEqual(104729, nth_prime(10000)) + + +if __name__ == '__main__': + unittest.main() diff --git a/ocr-numbers/example.py b/ocr-numbers/example.py new file mode 100644 index 00000000000..009f3030f88 --- /dev/null +++ b/ocr-numbers/example.py @@ -0,0 +1,16 @@ +def number(g): + if not g or len(g) < 4 or any(len(r)!=len(g[0]) for r in g): + raise ValueError('Ill-formed grid') + if g == [" _ ","| |","|_|"," "]: + return '0' + elif g == [" "," |"," |"," "]: + return '1' + else: + return '?' + +def grid(n): + if n == '0': + return [" _ ","| |","|_|"," "] + elif n == '1': + return [" "," |"," |"," "] + raise ValueError('Unknown digit') \ No newline at end of file diff --git a/ocr-numbers/ocr_test.py b/ocr-numbers/ocr_test.py new file mode 100644 index 00000000000..6134d3358e1 --- /dev/null +++ b/ocr-numbers/ocr_test.py @@ -0,0 +1,56 @@ +try: + from ocr import number, grid +except ImportError: + raise SystemExit('Could not find ocr.py. Does it exist?') + +import unittest + +class OcrTest(unittest.TestCase): + def test_0(self): + self.assertEqual('0', number([" _ ","| |","|_|"," "])) + + @unittest.skip("Not implemented yet") + def test_1(self): + self.assertEqual('1', number([" "," |"," |"," "])) + + @unittest.skip("Not implemented yet") + def test_garbage(self): + self.assertEqual('?', number([" _ "," _|"," |"," "])) + + @unittest.skip("Not implemented yet") + def test_last_line_nonblank(self): + self.assertEqual('?', number([" "," |"," |","| |"])) + + @unittest.skip("Not implemented yet") + def test_unknown_char(self): + self.assertEqual('?', number([" - "," _|"," X|"," "])) + + @unittest.skip("Not implemented yet") + def test_too_short_row(self): + with self.assertRaises(ValueError) as context: + number([" "," _|"," |"," "]) + self.assertEqual(context.exception.message, 'Ill-formed grid') + + @unittest.skip("Not implemented yet") + def test_insufficient_rows(self): + with self.assertRaises(ValueError) as context: + number([" "," _|"," X|"]) + self.assertEqual(context.exception.message, 'Ill-formed grid') + + @unittest.skip("Not implemented yet") + def test_grid0(self): + self.assertEqual([" _ ","| |","|_|"," "], grid('0')) + + @unittest.skip("Not implemented yet") + def test_grid1(self): + self.assertEqual([" "," |"," |"," "], grid('1')) + + @unittest.skip("Not implemented yet") + def test_invalid_digit(self): + with self.assertRaises(ValueError) as context: + grid('2') + self.assertEqual(context.exception.message, 'Unknown digit') + + +if __name__ == '__main__': + unittest.main() diff --git a/octal/example.py b/octal/example.py new file mode 100644 index 00000000000..b30b46b5c34 --- /dev/null +++ b/octal/example.py @@ -0,0 +1,13 @@ +class Octal(object): + def __init__(self, octal_string): + self.digits = self.__validate(octal_string) + + def __validate(self, s): + for char in s: + if not '0' <= char < '8': + raise ValueError("Invalid octal digit: " + char) + return s + + def to_decimal(self): + return sum(int(digit) * 8 ** i + for (i, digit) in enumerate(reversed(self.digits))) diff --git a/octal/octal_test.py b/octal/octal_test.py new file mode 100644 index 00000000000..1273a318f25 --- /dev/null +++ b/octal/octal_test.py @@ -0,0 +1,45 @@ +try: + from octal import Octal +except ImportError: + raise SystemExit('Could not find octal.py. Does it exist?') + +import unittest + + +class OctalTest(unittest.TestCase): + def test_octal_1_is_decimal_1(self): + self.assertEqual(1, Octal("1").to_decimal()) + + def test_octal_10_is_decimal_8(self): + self.assertEqual(8, Octal("10").to_decimal()) + + def test_octal_17_is_decimal_15(self): + self.assertEqual(15, Octal("17").to_decimal()) + + def test_octal_130_is_decimal_88(self): + self.assertEqual(88, Octal("130").to_decimal()) + + def test_octal_2047_is_decimal_1063(self): + self.assertEqual(1063, Octal("2047").to_decimal()) + + def test_octal_1234567_is_decimal_342391(self): + self.assertEqual(342391, Octal("1234567").to_decimal()) + + def test_8_is_seen_as_invalid(self): + self.assertRaisesRegexp(ValueError, "^Invalid octal digit: 8$", + Octal, "8") + + def test_invalid_octal_is_recognized(self): + self.assertRaisesRegexp(ValueError, "^Invalid octal digit: c$", + Octal, "carrot") + + def test_6789_is_seen_as_invalid(self): + self.assertRaisesRegexp(ValueError, "^Invalid octal digit: 8$", + Octal, "6789") + + def test_valid_octal_formatted_string_011_is_decimal_9(self): + self.assertEqual(9, Octal("011").to_decimal()) + + +if __name__ == '__main__': + unittest.main() diff --git a/palindrome-products/example.py b/palindrome-products/example.py new file mode 100644 index 00000000000..6d209b7f0fb --- /dev/null +++ b/palindrome-products/example.py @@ -0,0 +1,18 @@ +def largest_palindrome(max_factor, min_factor=0): + return max(palindromes(max_factor, min_factor), key=lambda tup: tup[0]) + + +def smallest_palindrome(max_factor, min_factor): + return min(palindromes(max_factor, min_factor), key=lambda tup: tup[0]) + + +def palindromes(max_factor, min_factor): + return ((a * b, (a, b)) + for a in range(min_factor, max_factor + 1) + for b in range(min_factor, a + 1) + if is_palindrome(a * b)) + + +def is_palindrome(n): + s = str(n) + return s == s[::-1] diff --git a/palindrome-products/palindrome_products_test.py b/palindrome-products/palindrome_products_test.py new file mode 100644 index 00000000000..9927e5323ee --- /dev/null +++ b/palindrome-products/palindrome_products_test.py @@ -0,0 +1,50 @@ +""" +Notes regarding the implementation of smallest_palindrome and +largest_palindrome: + +Both functions must take two keyword arguments: + max_factor -- int + min_factor -- int, default 0 + +Their return value must be a tuple (value, factors) where value is the +palindrome itself, and factors is an iterable containing both factors of the +palindrome in arbitrary order. +""" + +try: + from palindrome import smallest_palindrome, largest_palindrome +except ImportError: + raise SystemExit('Could not find palindrome.py. Does it exist?') + +import unittest + + +class PalindromesTests(unittest.TestCase): + def test_largest_palindrome_from_single_digit_factors(self): + value, factors = largest_palindrome(max_factor=9) + self.assertEqual(9, value) + self.assertIn(set(factors), [{1, 9}, {3, 3}]) + + def test_largest_palindrome_from_double_digit_factors(self): + value, factors = largest_palindrome(max_factor=99, min_factor=10) + self.assertEqual(9009, value) + self.assertEqual({91, 99}, set(factors)) + + def test_smallest_palindrome_from_double_digit_factors(self): + value, factors = smallest_palindrome(max_factor=99, min_factor=10) + self.assertEqual(121, value) + self.assertEqual({11}, set(factors)) + + def test_largest_palindrome_from_triple_digit_factors(self): + value, factors = largest_palindrome(max_factor=999, min_factor=100) + self.assertEqual(906609, value) + self.assertEqual({913, 993}, set(factors)) + + def test_smallest_palindrome_from_triple_digit_factors(self): + value, factors = smallest_palindrome(max_factor=999, min_factor=100) + self.assertEqual(10201, value) + self.assertEqual({101, 101}, set(factors)) + + +if __name__ == '__main__': + unittest.main() diff --git a/pascals-triangle/example.py b/pascals-triangle/example.py new file mode 100644 index 00000000000..47c74842e2a --- /dev/null +++ b/pascals-triangle/example.py @@ -0,0 +1,12 @@ +def triangle(nth): + return [row(i) for i in xrange(nth+1)] + +def is_triangle(t): + new_t = triangle(len(t)-1) + return t == new_t + +def row(nth): + r = [1] + for i in xrange(1,nth+1): + r.append(r[-1]*(nth-i+1)/i) + return " ".join([str(i) for i in r]) \ No newline at end of file diff --git a/pascals-triangle/pascals_triangle_test.py b/pascals-triangle/pascals_triangle_test.py new file mode 100644 index 00000000000..035014b0545 --- /dev/null +++ b/pascals-triangle/pascals_triangle_test.py @@ -0,0 +1,43 @@ +from pascals_triangle import triangle, row, is_triangle + +import unittest + +class PascalsTriangleTest(unittest.TestCase): + def test_triangle1(self): + ans = ['1', '1 1', '1 2 1', '1 3 3 1', '1 4 6 4 1'] + self.assertEqual(ans, triangle(4)) + + @unittest.skip("Not implemented yet") + def test_triangle2(self): + ans = ['1', '1 1', '1 2 1', '1 3 3 1', '1 4 6 4 1', '1 5 10 10 5 1', + '1 6 15 20 15 6 1'] + self.assertEqual(ans, triangle(6)) + + @unittest.skip("Not implemented yet") + def test_is_triangle_true(self): + inp = ['1', '1 1', '1 2 1', '1 3 3 1', '1 4 6 4 1', '1 5 10 10 5 1'] + self.assertEqual(True, is_triangle(inp)) + + @unittest.skip("Not implemented yet") + def test_is_triangle_false(self): + inp = ['1', '1 1', '1 2 1', '1 4 4 1'] + self.assertEqual(False, is_triangle(inp)) + + @unittest.skip("Not implemented yet") + def test_row1(self): + ans = '1' + self.assertEqual(ans, row(0)) + + @unittest.skip("Not implemented yet") + def test_row2(self): + ans = '1 2 1' + self.assertEqual(ans, row(2)) + + @unittest.skip("Not implemented yet") + def test_row3(self): + ans = '1 7 21 35 35 21 7 1' + self.assertEqual(ans, row(7)) + + +if __name__ == '__main__': + unittest.main() diff --git a/proverb/example.py b/proverb/example.py new file mode 100644 index 00000000000..dba9c9df952 --- /dev/null +++ b/proverb/example.py @@ -0,0 +1,7 @@ +def proverb(itens, qualifier=''): + phrases = ['For want of a {0} the {1} was lost.'.format(el1, el2) + for el1, el2 in zip(itens, itens[1:])] + qualifier += ' ' if qualifier else '' + phrases.append('And all for the want of a {0}{1}.'.format(qualifier, + itens[0])) + return '\n'.join(phrases) diff --git a/proverb/proverb_test.py b/proverb/proverb_test.py new file mode 100644 index 00000000000..26ac938187e --- /dev/null +++ b/proverb/proverb_test.py @@ -0,0 +1,55 @@ +from proverb import proverb + +import unittest + + +class ProverbTest(unittest.TestCase): + def test_a_single_consequence(self): + expected = 'For want of a nail the shoe was lost.\n'\ + 'And all for the want of a nail.' + self.assertEqual(expected, proverb(['nail', 'shoe'])) + + def test_short_list(self): + expected = 'For want of a nail the shoe was lost.\n'\ + 'For want of a shoe the horse was lost.\n'\ + 'And all for the want of a nail.' + self.assertEqual(expected, proverb(['nail', 'shoe', 'horse'])) + + def test_long_list(self): + expected = 'For want of a nail the shoe was lost.\n'\ + 'For want of a shoe the horse was lost.\n'\ + 'For want of a horse the rider was lost.\n'\ + 'And all for the want of a nail.' + self.assertEqual(expected, proverb(['nail', 'shoe', 'horse', 'rider'])) + + def test_new_itens(self): + expected = 'For want of a key the value was lost.\n'\ + 'And all for the want of a key.' + self.assertEqual(expected, proverb(['key', 'value'])) + + def test_whole_proverb(self): + expected = 'For want of a nail the shoe was lost.\n'\ + 'For want of a shoe the horse was lost.\n'\ + 'For want of a horse the rider was lost.\n'\ + 'For want of a rider the message was lost.\n'\ + 'For want of a message the battle was lost.\n'\ + 'For want of a battle the kingdom was lost.\n'\ + 'And all for the want of a nail.' + self.assertEqual(expected, proverb(['nail', 'shoe', 'horse', 'rider', + 'message', 'battle', 'kingdom'])) + + def test_qualifier(self): + expected = 'For want of a nail the shoe was lost.\n'\ + 'For want of a shoe the horse was lost.\n'\ + 'For want of a horse the rider was lost.\n'\ + 'For want of a rider the message was lost.\n'\ + 'For want of a message the battle was lost.\n'\ + 'For want of a battle the kingdom was lost.\n'\ + 'And all for the want of a horseshoe nail.' + self.assertEqual(expected, proverb(['nail', 'shoe', 'horse', 'rider', + 'message', 'battle', 'kingdom'], + qualifier='horseshoe')) + + +if __name__ == '__main__': + unittest.main() diff --git a/pythagorean-triplet/example.py b/pythagorean-triplet/example.py new file mode 100644 index 00000000000..3910a4089c5 --- /dev/null +++ b/pythagorean-triplet/example.py @@ -0,0 +1,72 @@ +from itertools import product +from operator import mul +from math import sqrt + +def primitive_triplets(nbr): + if nbr % 4 != 0: + raise ValueError('Argument must be divisible by 4') + prime_factors,powers = factor(nbr/2) + args = [(1,prime_factors[i1]**powers[i1]) for i1 in range(len(powers))] + a = [reduce(mul, p) for p in product(*args)] + a.sort() + factors = [(m,n) for m,n in zip(reversed(a),a) if m>n] + ts = set() + for m,n in factors: + l = [nbr, m*m-n*n,m*m+n*n] + l.sort() + ts.update([tuple(l)]) + return ts + +def is_triplet(t): + t = list(t) + t.sort() + a,b,c = t + return c*c == a*a + b*b + +def triplets_in_range(m, n): + t = set() + for a in xrange(m,n+1): + for b in xrange(a+1,n+1): + c = int(sqrt(a*a + b*b)+0.5) + if c*c == a*a + b*b and c >= m and c <= n: + t.update([(a,b,c)]) + return t + +primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, + 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, + 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, + 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, + 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, + 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, + 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, + 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, + 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, + 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, + 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, + 941, 947, 953, 967, 971, 977, 983, 991, 997] + +def factor(n): + global primes + if n == 1: + return (1,),(0,) + factors = [] + powers = [] + idx = 0 + while n > 1: + prime = primes[idx] + idx += 1 + if n % prime != 0: + continue + factors.append(prime) + p = 0 + while n % prime == 0: + p += 1 + n /= prime + powers.append(p) + return factors,powers + +if __name__ == '__main__': + print primitive_triplets(4) + print primitive_triplets(84) + print primitive_triplets(288) + print triplets_in_range(50,100) \ No newline at end of file diff --git a/pythagorean-triplet/pythagorean_triplet_test.py b/pythagorean-triplet/pythagorean_triplet_test.py new file mode 100644 index 00000000000..5e09b9d0dc6 --- /dev/null +++ b/pythagorean-triplet/pythagorean_triplet_test.py @@ -0,0 +1,93 @@ +# +#============================================================================== +# The test cases below assume two functions are defined: +# +# - triplets_in_range(min, max) +# Compute all pythagorean triplets (a,b,c) with min <= a,b,c <= max +# +# - primitive_triplets(b) +# Find all primitive pythagorean triplets having b as one of their +# components +# +# Args: +# b - an integer divisible by 4 (see explanantion below) +# +# Note that in the latter function the components other than the argument can +# be quite large. +# +# A primitive pythagorean triplet has its 3 componentes coprime. So, (3,4,5) is +# a primitive pythagorean triplet since 3,4 and 5 don't have a common factor. +# On the other hand, (6,8,10), although a pythagorean triplet, is not primitive +# aince 2 divides all three components. +# +# A method for finding all primitive pythagorean triplet is given in wikipedia +# (http://en.wikipedia.org/wiki/Pythagorean_triple#Generating_a_triple). The +# triplet a=(m^2-n^2), b=2*m*n and c=(m^2+n^2), where m and n are coprime and +# m-n>0 is odd, generate a primitive triplet. Note that this implies that b has +# to be divisible by 4 and a and c are odd. Also note that we may have either +# a>b or b>a. +# +# The function primitive_triplets should then use the formula above with b set +# to its argument and find all possible pairs (m,n) such that m>n, m-n is odd, +# b=2*m*n and m and n are coprime. +# +#============================================================================== + +from pythagorean_triplet import primitive_triplets, triplets_in_range, is_triplet + +import unittest + +class PythagoreanTripletTest(unittest.TestCase): + def test_triplet1(self): + ans = set([(3,4,5)]) + self.assertEqual(ans, primitive_triplets(4)) + +# @unittest.skip("Not implemented yet") + def test_triplet2(self): + ans = set([(13, 84, 85), (84, 187, 205), (84, 437, 445), + (84, 1763, 1765)]) + self.assertEqual(ans, primitive_triplets(84)) + +# @unittest.skip("Not implemented yet") + def test_triplet3(self): + ans = set([(29, 420, 421), (341, 420, 541), (420, 851, 949), + (420, 1189, 1261), (420, 1739, 1789), (420, 4891, 4909), + (420, 11021, 11029), (420, 44099, 44101)]) + self.assertEqual(ans, primitive_triplets(420)) + +# @unittest.skip("Not implemented yet") + def test_triplet4(self): + ans = set([(175, 288, 337), (288, 20735, 20737)]) + self.assertEqual(ans, primitive_triplets(288)) + +# @unittest.skip("Not implemented yet") + def test_range1(self): + ans = set([(3,4,5),(6,8,10)]) + self.assertEqual(ans, triplets_in_range(1, 10)) + +# @unittest.skip("Not implemented yet") + def test_range2(self): + ans = set([(57,76,95),(60,63,87)]) + self.assertEqual(ans, triplets_in_range(56, 95)) + +# @unittest.skip("Not implemented yet") + def test_is_triplet1(self): + self.assertEqual(True, is_triplet((29,20,21))) + +# @unittest.skip("Not implemented yet") + def test_is_triplet2(self): + self.assertEqual(False, is_triplet((25,25,1225))) + +# @unittest.skip("Not implemented yet") + def test_is_triplet3(self): + self.assertEqual(True, is_triplet((924,43,925))) + +# @unittest.skip("Not implemented yet") + def test_odd_number(self): + with self.assertRaises(ValueError) as context: + primitive_triplets(5) + self.assertEqual(context.exception.message, 'Argument must be divisible by 4') + + +if __name__ == '__main__': + unittest.main() diff --git a/queen-attack/example.py b/queen-attack/example.py new file mode 100644 index 00000000000..f6dbf039e0d --- /dev/null +++ b/queen-attack/example.py @@ -0,0 +1,27 @@ +def board(pos1, pos2): + validate_position(pos1, pos2) + x1, y1 = pos1 + x2, y2 = pos2 + b = [['0']*8 for i in range(8)] + b[x1][y1] = 'W' + b[x2][y2] = 'B' + return [''.join(r) for r in b] + + +def can_attack(pos1, pos2): + validate_position(pos1, pos2) + x1, y1 = pos1 + x2, y2 = pos2 + dx = x1 - x2 if x1 >= x2 else x2 - x1 + dy = y1 - y2 if y1 >= y2 else y2 - y1 + if dx == dy or dx == 0 or dy == 0: + return True + return False + + +def validate_position(pos1, pos2): + if any(x < 0 or x > 7 for x in pos1 + pos2): + raise ValueError('Invalid queen position: queen out of the board') + if pos1 == pos2: + raise ValueError('Invalid queen position: both queens in the same ' + 'square: {0}'.format(pos1)) diff --git a/queen-attack/queen_attack_test.py b/queen-attack/queen_attack_test.py new file mode 100644 index 00000000000..2b43a2cc456 --- /dev/null +++ b/queen-attack/queen_attack_test.py @@ -0,0 +1,61 @@ +from queen_attack import board, can_attack + +import unittest + + +class QueenAttackTest(unittest.TestCase): + def test_board1(self): + ans = ['00000000', '00000000', '000W0000', '00000000', + '00000000', '000000B0', '00000000', '00000000'] + self.assertEqual(ans, board((2, 3), (5, 6))) + + def test_board2(self): + ans = ['000000W0', '0000000B', '00000000', '00000000', + '00000000', '00000000', '00000000', '00000000'] + self.assertEqual(ans, board((0, 6), (1, 7))) + + def test_attack_true1(self): + self.assertEqual(True, can_attack((2, 3), (5, 6))) + + def test_attack_true2(self): + self.assertEqual(True, can_attack((2, 6), (5, 3))) + + def test_attack_true3(self): + self.assertEqual(True, can_attack((2, 4), (2, 7))) + + def test_attack_true4(self): + self.assertEqual(True, can_attack((5, 4), (2, 4))) + + def test_attack_true5(self): + self.assertEqual(True, can_attack((1, 1), (6, 6))) + + def test_attack_true6(self): + self.assertEqual(True, can_attack((0, 6), (1, 7))) + + def test_attack_false1(self): + self.assertEqual(False, can_attack((4, 2), (0, 5))) + + def test_attack_false2(self): + self.assertEqual(False, can_attack((2, 3), (4, 7))) + + # If either board or can_attack are called with an invalid board position + # they should raise a ValueError with a meaningful error message. + def test_invalid_position_board(self): + with self.assertRaises(ValueError): + board((0, 0), (7, 8)) + + def test_invalid_position_can_attack(self): + with self.assertRaises(ValueError): + can_attack((0, 0), (7, 8)) + + def test_queens_same_position_board(self): + with self.assertRaises(ValueError): + board((2, 2), (2, 2)) + + def test_queens_same_position_can_attack(self): + with self.assertRaises(ValueError): + can_attack((2, 2), (2, 2)) + + +if __name__ == '__main__': + unittest.main() diff --git a/saddle-points/example.py b/saddle-points/example.py new file mode 100644 index 00000000000..11ee4266dbd --- /dev/null +++ b/saddle-points/example.py @@ -0,0 +1,10 @@ +def saddle_points(m): + if not m: + return set() + if any(len(r)!=len(m[0]) for r in m): + raise ValueError('irregular matrix') + mmax = [max(r) for r in m] + mmin = [min(c) for c in zip(*m)] + points = [(i,j) for i in range(len(m)) for j in range(len(m[0])) if mmax[i] == mmin[j]] + + return set(points) diff --git a/saddle-points/saddle_points_test.py b/saddle-points/saddle_points_test.py new file mode 100644 index 00000000000..3daa1ff761a --- /dev/null +++ b/saddle-points/saddle_points_test.py @@ -0,0 +1,27 @@ +from saddle_points import saddle_points + +import unittest + +class SaddlePointTest(unittest.TestCase): + def test_one_saddle(self): + inp = [[9,8,7],[5,3,2],[6,6,7]] + self.assertEqual(set([(1,0)]), saddle_points(inp)) + + def test_no_saddle(self): + self.assertEqual(set(), saddle_points([[2,1],[1,2]])) + + def test_mult_saddle(self): + inp = [[5,3,5,4],[6,4,7,3],[5,1,5,3]] + ans = set([(0,0),(0,2),(2,0),(2,2)]) + self.assertEqual(ans, saddle_points(inp)) + + def test_empty_matrix(self): + self.assertEqual(set(), saddle_points([])) + + def test_irregular_matrix(self): + with self.assertRaisesRegexp(ValueError, 'irregular matrix'): + saddle_points([[1,2,3],[2,3],[3,2,1]]) + + +if __name__ == '__main__': + unittest.main() diff --git a/secret-handshake/example.py b/secret-handshake/example.py new file mode 100644 index 00000000000..efb165c57d8 --- /dev/null +++ b/secret-handshake/example.py @@ -0,0 +1,46 @@ +gestures = ['wink','double blink','close your eyes','jump'] + +def handshake(s): + s = list(sanitize(s)) + s.reverse() + seq = [] + lim = len(s) if len(s) <= len(gestures) else len(gestures) + for i1 in range(lim): + if s[i1] == '1': + seq.append(gestures[i1]) + if len(s) == 5: + seq.reverse() + return seq + +def code(seq): + if not seq or set(seq)-set(gestures): + return '0' + s = find_subseq(seq) + if not s: + s = ['1'] + find_subseq(reversed(seq)) + return "".join(s) + +def sanitize(s): + if not(isinstance(s, int) or isinstance(s,str)): + raise TypeError('Unknown type') + if isinstance(s,int): + if s < 0: + return "" + s = bin(s)[2:] + elif set(s)-set(['0','1']): + return "" + if len(s) > 5: + raise ValueError('Binary string too long') + return "0"*(len(gestures)-len(s)) + s + +def find_subseq(seq): + idx = 0 + s = [] + for g in seq: + if g not in gestures[idx:]: + return [] + newidx = gestures.index(g,idx) + 1 + s.extend(['0']*(newidx-idx-1)+['1']) + idx = newidx + s.reverse() + return s \ No newline at end of file diff --git a/secret-handshake/handshake_test.py b/secret-handshake/handshake_test.py new file mode 100644 index 00000000000..48d35a01794 --- /dev/null +++ b/secret-handshake/handshake_test.py @@ -0,0 +1,60 @@ +from handshake import handshake, code + +import unittest + +class HandshakeTest(unittest.TestCase): + def test_shake_int(self): + self.assertEqual(['wink','jump'], handshake(9)) + + @unittest.skip("Not implemented yet") + def test_shake_bin1(self): + self.assertEqual(['close your eyes','double blink'], handshake('10110')) + + @unittest.skip("Not implemented yet") + def test_shake_bin2(self): + self.assertEqual(['wink','close your eyes'], handshake('101')) + + @unittest.skip("Not implemented yet") + def test_shake_negative_int(self): + self.assertEqual([], handshake(-9)) + + @unittest.skip("Not implemented yet") + def test_shake_bin_invalid(self): + self.assertEqual([], handshake('121')) + + @unittest.skip("Not implemented yet") + def test_unknown_action(self): + self.assertEqual('0', code(['wink','sneeze'])) + + @unittest.skip("Not implemented yet") + def test_code1(self): + self.assertEqual('1100', code(['close your eyes','jump'])) + + @unittest.skip("Not implemented yet") + def test_code2(self): + self.assertEqual('11', code(['wink','double blink'])) + + @unittest.skip("Not implemented yet") + def test_code3(self): + self.assertEqual('11010', code(['jump','double blink'])) + + @unittest.skip("Not implemented yet") + def test_composition1(self): + self.assertEqual('11011', code(handshake(27))) + + @unittest.skip("Not implemented yet") + def test_composition2(self): + self.assertEqual('1', code(handshake(1))) + + @unittest.skip("Not implemented yet") + def test_composition3(self): + self.assertEqual('111', code(handshake('111'))) + + @unittest.skip("Not implemented yet") + def test_composition4(self): + inp = ['wink','double blink','jump'] + self.assertEqual(inp, handshake(code(inp))) + + +if __name__ == '__main__': + unittest.main() diff --git a/series/example.py b/series/example.py new file mode 100644 index 00000000000..44ebaaabc61 --- /dev/null +++ b/series/example.py @@ -0,0 +1,11 @@ +class Series(object): + def __init__(self, digits): + self.digits = digits + self.numbers = [int(d) for d in digits] + + def slices(self, length): + if not 1 <= length <= len(self.numbers): + raise ValueError("Invalid slice length for this series: " + + str(length)) + return [self.numbers[i:i + length] + for i in range(len(self.numbers) - length + 1)] diff --git a/series/series_test.py b/series/series_test.py new file mode 100644 index 00000000000..e32696a0ba6 --- /dev/null +++ b/series/series_test.py @@ -0,0 +1,44 @@ +try: + from series import Series +except ImportError: + raise SystemExit('Could not find series.py. Does it exist?') + +import unittest + + +class SeriesTest(unittest.TestCase): + def test_slices_of_one(self): + self.assertEqual([[0], [1], [2], [3], [4]], + Series("01234").slices(1)) + + def test_slices_of_two(self): + self.assertEqual([[9, 7], [7, 8], [8, 6], [6, 7], + [7, 5], [5, 6], [6, 4]], + Series("97867564").slices(2)) + + def test_slices_of_three(self): + self.assertEqual([[9, 7, 8], [7, 8, 6], [8, 6, 7], + [6, 7, 5], [7, 5, 6], [5, 6, 4]], + Series("97867564").slices(3)) + + def test_slices_of_four(self): + self.assertEqual([[0, 1, 2, 3], [1, 2, 3, 4]], + Series("01234").slices(4)) + + def test_slices_of_five(self): + self.assertEqual([[0, 1, 2, 3, 4]], + Series("01234").slices(5)) + + def test_overly_long_slice(self): + self.assertRaisesRegexp(ValueError, + "^Invalid slice length for this series: 4$", + Series("012").slices, 4) + + def test_overly_short_slice(self): + self.assertRaisesRegexp(ValueError, + "^Invalid slice length for this series: 0$", + Series("01234").slices, 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/simple-cipher/example.py b/simple-cipher/example.py new file mode 100644 index 00000000000..449331712be --- /dev/null +++ b/simple-cipher/example.py @@ -0,0 +1,34 @@ +from string import ascii_lowercase,punctuation,whitespace,digits +from time import time +import random + +class Cipher: + def __init__(self, k=None): + if k: + self.key = k.translate(None,punctuation+whitespace+digits).lower() + else: + random.seed(time()) + self.key = ''.join(random.choice(ascii_lowercase) for i in range(100)) + + def base_encode(self, s, shift): + xkey = self.key*(len(s)//len(self.key)+1) + return ''.join(shift(c,k) for c,k in zip(s,xkey)) + + def encode(self, s): + s = s.translate(None,punctuation+whitespace+digits).lower() + shift = lambda c,k: chr(((ord(c)+ord(k)-2*ord('a'))\ + % len(ascii_lowercase)) + ord('a')) + return self.base_encode(s, shift) + + def decode(self, s): + shift = lambda c,k: chr(((ord(c)-ord(k)+len(ascii_lowercase))\ + % len(ascii_lowercase)) + ord('a')) + return self.base_encode(s, shift) + +class Caesar(Cipher): + def __init__(self): + Cipher.__init__(self, 'd') + +if __name__ == '__main__': + print(Caesar().encode('venividivici')) + print(Caesar().encode('\'Twas the night before Christmas')) \ No newline at end of file diff --git a/simple-cipher/simple_cipher_test.py b/simple-cipher/simple_cipher_test.py new file mode 100644 index 00000000000..cb539b0e63a --- /dev/null +++ b/simple-cipher/simple_cipher_test.py @@ -0,0 +1,55 @@ +from cipher import Caesar, Cipher + +import unittest + +class CipherTest(unittest.TestCase): + def test_caesar_encode1(self): + self.assertEqual('lwlvdzhvrphsurjudpplqjlqsbwkrq', + Caesar().encode('itisawesomeprogramminginpython')) + + def test_caesar_encode2(self): + self.assertEqual('yhqlylglylfl', Caesar().encode('venividivici')) + + def test_caesar_encode3(self): + self.assertEqual('wzdvwkhqljkwehiruhfkulvwpdv', + Caesar().encode('\'Twas the night before Christmas')) + + def test_caesar_encode_with_numbers(self): + self.assertEqual('jr', Caesar().encode('1, 2, 3, Go!')) + + def test_caesar_decode(self): + self.assertEqual('venividivici', Caesar().decode('yhqlylglylfl')) + + def test_cipher_encode1(self): + c = Cipher('a') + self.assertEqual('itisawesomeprogramminginpython', + c.encode('itisawesomeprogramminginpython')) + + def test_cipher_encode2(self): + c = Cipher('aaaaaaaaaaaaaaaaaaaaaa') + self.assertEqual('itisawesomeprogramminginpython', + c.encode('itisawesomeprogramminginpython')) + + def test_cipher_encode3(self): + c = Cipher('dddddddddddddddddddddd') + self.assertEqual('yhqlylglylfl', c.encode('venividivici')) + + def test_cipher_encode4(self): + key = 'duxrceqyaimciuucnelkeoxjhdyduucpmrxmaivacmybmsdrzwqxvbxsygzsabdjmdjabeorttiwinfrpmpogvabiofqexnohrqu' + c = Cipher(key) + self.assertEqual('gccwkixcltycv', c.encode('diffiehellman')) + + def test_cipher_compositiion1(self): + key = 'duxrceqyaimciuucnelkeoxjhdyduucpmrxmaivacmybmsdrzwqxvbxsygzsabdjmdjabeorttiwinfrpmpogvabiofqexnohrqu' + plaintext = 'adaywithoutlaughterisadaywasted' + c = Cipher(key) + self.assertEqual(plaintext, c.decode(c.encode(plaintext))) + + def test_cipher_compositiion2(self): + plaintext = 'adaywithoutlaughterisadaywasted' + c = Cipher() + self.assertEqual(plaintext, c.decode(c.encode(plaintext))) + + +if __name__ == '__main__': + unittest.main() diff --git a/strain/example.py b/strain/example.py new file mode 100644 index 00000000000..6069fc751fd --- /dev/null +++ b/strain/example.py @@ -0,0 +1,14 @@ +def keep(seq, pred): + res = [] + for el in seq: + if pred(el): + res.append(el) + return res + + +def discard(seq, pred): + res = [] + for el in seq: + if not pred(el): + res.append(el) + return res diff --git a/strain/strain_test.py b/strain/strain_test.py new file mode 100644 index 00000000000..1ba9326b30d --- /dev/null +++ b/strain/strain_test.py @@ -0,0 +1,46 @@ +from strain import keep, discard + +import unittest + + +class StrainTest(unittest.TestCase): + def test_empty_sequence(self): + self.assertEqual([], keep([], lambda x: x % 2 == 0)) + + def test_empty_keep(self): + inp = [2, 4, 6, 8, 10] + out = [] + self.assertEqual(out, keep(inp, lambda x: x % 2 == 1)) + + def test_empty_discard(self): + inp = [2, 4, 6, 8, 10] + out = [] + self.assertEqual(out, discard(inp, lambda x: x % 2 == 0)) + + def test_keep_everything(self): + inp = [2, 4, 6, 8, 10] + self.assertEqual(inp, keep(inp, lambda x: x % 2 == 0)) + + def test_discard_endswith(self): + inp = ['dough', 'cash', 'plough', 'though', 'through', 'enough'] + out = ['cash'] + fn = lambda x: str.endswith(x, 'ough') + self.assertEqual(out, discard(inp, fn)) + + def test_keep_z(self): + inp = ['zebra', 'arizona', 'apple', 'google', 'mozilla'] + out = ['zebra', 'arizona', 'mozilla'] + self.assertEqual(out, keep(inp, lambda x: 'z' in x)) + + def test_keep_discard(self): + inp = ['1,2,3', 'one', 'almost!', 'love'] + self.assertEqual([], discard(keep(inp, str.isalpha), str.isalpha)) + + def test_keep_plus_discard(self): + inp = ['1,2,3', 'one', 'almost!', 'love'] + out = ['one', 'love', '1,2,3', 'almost!'] + self.assertEqual(out, keep(inp, str.isalpha)+discard(inp, str.isalpha)) + + +if __name__ == '__main__': + unittest.main() diff --git a/sublist/example.py b/sublist/example.py new file mode 100644 index 00000000000..63470e27c0a --- /dev/null +++ b/sublist/example.py @@ -0,0 +1,33 @@ +SUBLIST = 0 +SUPERLIST = 1 +EQUAL = 2 +UNEQUAL = 3 + + +def check_lists(l1, l2): + if l1 == l2: + return EQUAL + if l1 == []: + return SUBLIST + if l2 == []: + return SUPERLIST + if is_sublist(l1, l2): + return SUBLIST + if is_sublist(l2, l1): + return SUPERLIST + return UNEQUAL + + +def is_sublist(l1, l2): + if len(l1) > len(l2): + return False + idx = -1 + while 1: + try: + idx = l2.index(l1[0], idx+1) + except ValueError: + return False + if len(l1) > len(l2) - idx: + return False + if all(el1 == el2 for el1, el2 in zip(l1, l2[idx:])): + return True diff --git a/sublist/sublist_test.py b/sublist/sublist_test.py new file mode 100644 index 00000000000..51d4cf3b01b --- /dev/null +++ b/sublist/sublist_test.py @@ -0,0 +1,79 @@ +from sublist import check_lists, SUBLIST, SUPERLIST, EQUAL, UNEQUAL + +import unittest + + +class SublistTest(unittest.TestCase): + def test_empty_lists(self): + self.assertEqual(EQUAL, check_lists([], [])) + + def test_empty_list_within(self): + self.assertEqual(SUBLIST, check_lists([], [1, 2, 3])) + + def test_within_empty_list(self): + self.assertEqual(SUPERLIST, check_lists([1], [])) + + def test_equal_lists(self): + l1 = [0, 1, 2] + l2 = [0, 1, 2] + self.assertEqual(EQUAL, check_lists(l1, l2)) + + def test_different_lists(self): + l1 = list(range(1000000)) + l2 = list(range(1, 1000001)) + self.assertEqual(UNEQUAL, check_lists(l1, l2)) + + def test_false_start(self): + l1 = [1, 2, 5] + l2 = [0, 1, 2, 3, 1, 2, 5, 6] + self.assertEqual(SUBLIST, check_lists(l1, l2)) + + def test_consecutive(self): + l1 = [1, 1, 2] + l2 = [0, 1, 1, 1, 2, 1, 2] + self.assertEqual(SUBLIST, check_lists(l1, l2)) + + def test_sublist_at_start(self): + l1 = [0, 1, 2] + l2 = [0, 1, 2, 3, 4, 5] + self.assertEqual(SUBLIST, check_lists(l1, l2)) + + def test_sublist_in_middle(self): + l1 = [2, 3, 4] + l2 = [0, 1, 2, 3, 4, 5] + self.assertEqual(SUBLIST, check_lists(l1, l2)) + + def test_sublist_at_end(self): + l1 = [3, 4, 5] + l2 = [0, 1, 2, 3, 4, 5] + self.assertEqual(SUBLIST, check_lists(l1, l2)) + + def test_at_start_of_superlist(self): + l1 = [0, 1, 2, 3, 4, 5] + l2 = [0, 1, 2] + self.assertEqual(SUPERLIST, check_lists(l1, l2)) + + def test_in_middle_of_superlist(self): + l1 = [0, 1, 2, 3, 4, 5] + l2 = [2, 3] + self.assertEqual(SUPERLIST, check_lists(l1, l2)) + + def test_at_end_of_superlist(self): + l1 = [0, 1, 2, 3, 4, 5] + l2 = [3, 4, 5] + self.assertEqual(SUPERLIST, check_lists(l1, l2)) + + def test_large_lists(self): + l1 = list(range(1000))*1000 + list(range(1000, 1100)) + l2 = list(range(900, 1050)) + self.assertEqual(SUPERLIST, check_lists(l1, l2)) + + def test_spread_sublist(self): + multiples_of_3 = list(range(3, 200, 3)) + multiples_of_15 = list(range(3, 200, 15)) + self.assertEqual(UNEQUAL, + check_lists(multiples_of_15, multiples_of_3)) + + +if __name__ == '__main__': + unittest.main() diff --git a/sum-of-multiples/example.py b/sum-of-multiples/example.py new file mode 100644 index 00000000000..cd993c6407d --- /dev/null +++ b/sum-of-multiples/example.py @@ -0,0 +1,13 @@ +class SumOfMultiples(object): + + def __init__(self, *args): + self.numbers = args if args else [3, 5] + + def to(self, limit): + return sum(n + for n in range(limit) + if self.is_multiple(n)) + + def is_multiple(self, m): + return any(m % n == 0 + for n in self.numbers) diff --git a/sum-of-multiples/sum_of_multiples_test.py b/sum-of-multiples/sum_of_multiples_test.py new file mode 100644 index 00000000000..f15a2c07e5a --- /dev/null +++ b/sum-of-multiples/sum_of_multiples_test.py @@ -0,0 +1,30 @@ +try: + from sum_of_multiples import SumOfMultiples +except ImportError: + raise SystemExit('Could not find sum_of_multiples.py. Does it exist?') + +import unittest + + +class SumOfMultiplesTest(unittest.TestCase): + def test_sum_to_1(self): + self.assertEqual(0, SumOfMultiples().to(1)) + + def test_sum_to_3(self): + self.assertEqual(3, SumOfMultiples().to(4)) + + def test_sum_to_10(self): + self.assertEqual(23, SumOfMultiples().to(10)) + + def test_sum_to_1000(self): + self.assertEqual(233168, SumOfMultiples().to(1000)) + + def test_configurable_7_13_17_to_20(self): + self.assertEqual(51, SumOfMultiples(7, 13, 17).to(20)) + + def test_configurable_43_47_to_10000(self): + self.assertEqual(2203160, SumOfMultiples(43, 47).to(10000)) + + +if __name__ == '__main__': + unittest.main() diff --git a/trinary/example.py b/trinary/example.py new file mode 100644 index 00000000000..a1a18e0324f --- /dev/null +++ b/trinary/example.py @@ -0,0 +1,9 @@ +def trinary(s): + if set(s) - set('012'): + return 0 + return reduce(lambda x,y:x*3 + int(y), s, 0) + +if __name__ == '__main__': + print trinary('102101') + print trinary('22222') + print trinary('10000') diff --git a/trinary/trinary_test.py b/trinary/trinary_test.py new file mode 100644 index 00000000000..204c166d7a1 --- /dev/null +++ b/trinary/trinary_test.py @@ -0,0 +1,29 @@ +from trinary import trinary + +import unittest + +class TrinaryTest(unittest.TestCase): + def test_valid_trinary1(self): + self.assertEqual(0, trinary('0')) + + def test_valid_trinary2(self): + self.assertEqual(1, trinary('1')) + + def test_valid_trinary3(self): + self.assertEqual(3, trinary('10')) + + def test_valid_trinary4(self): + self.assertEqual(307, trinary('102101')) + + def test_valid_trinary5(self): + self.assertEqual(242, trinary('22222')) + + def test_valid_trinary6(self): + self.assertEqual(81, trinary('10000')) + + def test_invalid_trinary(self): + self.assertEqual(0, trinary('13201')) + + +if __name__ == '__main__': + unittest.main() diff --git a/twelve-days/example.py b/twelve-days/example.py new file mode 100644 index 00000000000..029a142750c --- /dev/null +++ b/twelve-days/example.py @@ -0,0 +1,33 @@ +GIFTS = ['twelve Drummers Drumming', + 'eleven Pipers Piping', + 'ten Lords-a-Leaping', + 'nine Ladies Dancing', + 'eight Maids-a-Milking', + 'seven Swans-a-Swimming', + 'six Geese-a-Laying', + 'five Gold Rings', + 'four Calling Birds', + 'three French Hens', + 'two Turtle Doves', + 'a Partridge in a Pear Tree'] + +ORDINAL = [None, 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', + 'seventh', 'eighth', 'ninth', 'tenth', 'eleventh', 'twelfth'] + + +def verse(n): + gifts = GIFTS[-n:] + if len(gifts) > 1: + gifts[:-1] = [', '.join(gifts[:-1])] + gifts = ', and '.join(gifts) + return 'On the {} day of Christmas my true love gave to me, {}.\n'.format( + ORDINAL[n], gifts) + + +def verses(start, end): + return ''.join([verse(n) + '\n' + for n in range(start, end + 1)]) + + +def sing(): + return verses(1, 12) diff --git a/twelve-days/twelve_days_test.py b/twelve-days/twelve_days_test.py new file mode 100644 index 00000000000..d60ce28e936 --- /dev/null +++ b/twelve-days/twelve_days_test.py @@ -0,0 +1,71 @@ +try: + from twelve_days import sing, verse, verses +except ImportError: + raise SystemExit('Could not find twelve_days.py. Does it exist?') + +import unittest + + +class TwelveDaysTests(unittest.TestCase): + + def test_verse1(self): + expected = "On the first day of Christmas my true love gave to me, a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(1)) + + def test_verse2(self): + expected = "On the second day of Christmas my true love gave to me, two Turtle Doves, and a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(2)) + + def test_verse3(self): + expected = "On the third day of Christmas my true love gave to me, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(3)) + + def test_verse4(self): + expected = "On the fourth day of Christmas my true love gave to me, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(4)) + + def test_verse5(self): + expected = "On the fifth day of Christmas my true love gave to me, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(5)) + + def test_verse6(self): + expected = "On the sixth day of Christmas my true love gave to me, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(6)) + + def test_verse7(self): + expected = "On the seventh day of Christmas my true love gave to me, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(7)) + + def test_verse8(self): + expected = "On the eighth day of Christmas my true love gave to me, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(8)) + + def test_verse9(self): + expected = "On the ninth day of Christmas my true love gave to me, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(9)) + + def test_verse10(self): + expected = "On the tenth day of Christmas my true love gave to me, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(10)) + + def test_verse11(self): + expected = "On the eleventh day of Christmas my true love gave to me, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(11)) + + def test_verse12(self): + expected = "On the twelfth day of Christmas my true love gave to me, twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n" + self.assertEqual(expected, verse(12)) + + def test_multiple_verses(self): + expected = ( + "On the first day of Christmas my true love gave to me, a Partridge in a Pear Tree.\n\n" + + "On the second day of Christmas my true love gave to me, two Turtle Doves, and a Partridge in a Pear Tree.\n\n" + + "On the third day of Christmas my true love gave to me, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n\n") + self.assertEqual(expected, verses(1, 3)) + + def test_the_whole_song(self): + self.assertEqual(verses(1, 12), sing()) + + +if __name__ == '__main__': + unittest.main() diff --git a/wordy/example.py b/wordy/example.py new file mode 100644 index 00000000000..7e0fda310fb --- /dev/null +++ b/wordy/example.py @@ -0,0 +1,33 @@ +from operator import add, div, mul, sub + +VALID_OPERATIONS = {"plus": add, "minus": sub, "times": mul, + "multiplied by": mul, "divided by": div} + +def calculate(stmt): + if not (stmt.startswith("What is ") and stmt.endswith("?")): + raise ValueError("Ill-formed question") + l = stmt[8:-1].strip().lower().split() + if not l: + raise ValueError("Ill-formed question") + l.reverse() + try: + op1 = int(l.pop()) + except ValueError: + raise ValueError("Ill-formed question") + while l: + oprt = [l.pop()] + while l: + try: + next_tk = l.pop() + op2 = int(next_tk) + break + except ValueError: + oprt.append(next_tk) + else: + raise ValueError("Ill-formed question") + oprt = " ".join(oprt) + try: + op1 = VALID_OPERATIONS[oprt](op1, op2) + except KeyError: + raise ValueError("Ill-formed question") + return op1 \ No newline at end of file diff --git a/wordy/wordy_test.py b/wordy/wordy_test.py new file mode 100644 index 00000000000..0ddd0218d4e --- /dev/null +++ b/wordy/wordy_test.py @@ -0,0 +1,90 @@ +try: + from wordy import calculate +except ImportError: + raise SystemExit('Could not find wordy.py. Does it exist?') + +import unittest + +class WordyTest(unittest.TestCase): + def test_simple_add_1(self): + self.assertEqual(18, calculate("What is 5 plus 13?")) + + @unittest.skip("Not implemented yet") + def test_simple_add_2(self): + self.assertEqual(-8, calculate("What is 5 plus -13?")) + + @unittest.skip("Not implemented yet") + def test_simple_sub_1(self): + self.assertEqual(6, calculate("What is 103 minus 97?")) + + @unittest.skip("Not implemented yet") + def test_simple_sub_2(self): + self.assertEqual(-6, calculate("What is 97 minus 103?")) + + @unittest.skip("Not implemented yet") + def test_simple_mult(self): + self.assertEqual(21, calculate("What is 7 times 3?")) + + @unittest.skip("Not implemented yet") + def test_simple_div(self): + self.assertEqual(9, calculate("What is 45 divided by 5?")) + + @unittest.skip("Not implemented yet") + def test_add_negative_numbers(self): + self.assertEqual(-11, calculate("What is -1 plus -10?")) + + @unittest.skip("Not implemented yet") + def test_add_more_digits(self): + self.assertEqual(45801, calculate("What is 123 plus 45678?")) + + @unittest.skip("Not implemented yet") + def test_add_twice(self): + self.assertEqual(4, calculate("What is 1 plus 2 plus 1?")) + + @unittest.skip("Not implemented yet") + def test_add_then_subtract(self): + self.assertEqual(14, calculate("What is 1 plus 5 minus -8?")) + + @unittest.skip("Not implemented yet") + def test_subtract_twice(self): + self.assertEqual(-7, calculate("What is 20 minus 14 minus 13?")) + + @unittest.skip("Not implemented yet") + def test_multiply_twice(self): + self.assertEqual(-12, calculate("What is 2 multiplied by -2 multiplied by 3?")) + + @unittest.skip("Not implemented yet") + def test_add_then_multiply(self): + self.assertEqual(-8, calculate("What is -3 plus 7 multiplied by -2?")) + + @unittest.skip("Not implemented yet") + def test_divide_twice(self): + self.assertEqual(16, calculate("What is -12000 divided by 25 divided by -30?")) + + @unittest.skip("Not implemented yet") + def test_invalid_operation(self): + with self.assertRaises(ValueError) as context: + calculate("What is 4 xor 7?") + self.assertEqual(context.exception.message, 'Ill-formed question') + + @unittest.skip("Not implemented yet") + def test_missing_operation(self): + with self.assertRaises(ValueError) as context: + calculate("What is 2 2 minus 3?") + self.assertEqual(context.exception.message, 'Ill-formed question') + + @unittest.skip("Not implemented yet") + def test_missing_number(self): + with self.assertRaises(ValueError) as context: + calculate("What is 7 plus times -2?") + self.assertEqual(context.exception.message, 'Ill-formed question') + + @unittest.skip("Not implemented yet") + def test_irrelevant_question(self): + with self.assertRaises(ValueError) as context: + calculate("Which is greater, 3 or 2?") + self.assertEqual(context.exception.message, 'Ill-formed question') + + +if __name__ == '__main__': + unittest.main()